240
JBoss Enterprise BRMS Platform 5 JBoss Rules 5 リファレンスガイド 開発者向け エディッション 5.3.1 Last Updated: 2017-11-22

JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

JBoss Enterprise BRMS Platform 5

JBoss Rules 5 リファレンスガイド

開発者向けエディッション 5.3.1

Last Updated: 2017-11-22

Page 2: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE
Page 3: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

JBoss Enterprise BRMS Platform 5 JBoss Rules 5 リファレンスガイド

開発者向けエディッション 5.3.1

David Le SageRed Hat Engineering Content [email protected]

Page 4: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

法律上の通知法律上の通知

Copyright © 2014 Red Hat, Inc..

This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0Unported License. If you distribute this document, or a modified version of it, you must provideattribution to Red Hat, Inc. and provide a link to the original. If the document is modified, all RedHat trademarks must be removed.

Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert,Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.

Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinitylogo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and othercountries.

Linux ® is the registered trademark of Linus Torvalds in the United States and other countries.

Java ® is a registered trademark of Oracle and/or its affiliates.

XFS ® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the UnitedStates and/or other countries.

MySQL ® is a registered trademark of MySQL AB in the United States, the European Union andother countries.

Node.js ® is an official trademark of Joyent. Red Hat Software Collections is not formally relatedto or endorsed by the official Joyent Node.js open source or commercial project.

The OpenStack ® Word Mark and OpenStack logo are either registered trademarks/service marksor trademarks/service marks of the OpenStack Foundation, in the United States and othercountries and are used with the OpenStack Foundation's permission. We are not affiliated with,endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.

All other trademarks are the property of their respective owners.

概要概要

本書では、開発者向けに JBoss Rules を説明します。

Page 5: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

目次目次

前書き前書き

第第1章章 はじめにはじめに1.1. 対象読者1.2. 本書の目的

第第2章章 クイックスタートクイックスタート2.1. JBOSS RULES2.2. JBOSS RULES エンジン2.3. プロダクションルール2.4. 推論エンジン2.5. RETEOO2.6. プロダクションメモリ2.7. ワーキングメモリ2.8. 競合解消 (CONFLICT RESOLUTION) 戦略2.9. ハイブリッドルールシステム2.10. 前向き連鎖2.11. 後向き連鎖2.12. 推論機能2.13. エキスパートシステム2.14. RETE ROOT ノード2.15. OBJECTTYPENODE2.16. ALPHANODES2.17. ハッシュ2.18. BETANODES2.19. アルファメモリ2.20. ベータメモリ2.21. BETANODES を用いたルックアップ2.22. LEFTINPUTNODEADAPTERS2.23. 終端ノード2.24. ノード共有2.25. ノード共有の例2.26. 疎結合2.27. 密結合2.28. 宣言型プログラミング2.29. 論理とデータの分離2.30. ナレッジベース

第第3章章 ユーザーガイドユーザーガイド3.1. ステートレスナレッジセッション3.2. ステートレスセッションでのルールの設定3.3. 複数のオブジェクトを使用したルールの設定3.4. ステートフルセッション3.5. ステートフルセッションセッションの一般的なユースケース3.6. ステートフルセッションの監査の例3.7. 一階論理3.8. 一階論理を使ったルール設定3.9. ルールシステムの設定サンプル3.10. JBOSS RULES のメソッド3.11. メソッドの例3.12. ルールの例3.13. クロスプロダクト

12

131313

14141414141414141515151515151616161616171717171717171818181819

2020202123232425252627282828

目次目次

1

Page 6: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.14. クロスプロダクトの制約3.15. 推論エンジン3.16. 推論の例3.17. 論理アサーション3.18. 記述 (STATED) 挿入3.19. 正当化 (JUSTIFIED) 挿入3.20. WM_BEHAVIOR_PRESERVE 設定3.21. 記述挿入のフローチャート3.22. 論理挿入のフローチャート3.23. 真理維持システム3.24. INSERTLOGICAL ファクト3.25. 推論と TMS の使用

第第4章章 決定表決定表4.1. 決定表4.2. スプレッドシート4.3. OPEN OFFICE の例4.4. ルールとスプレッドシート4.5. RULETABLE のキーワード4.6. RULESET キーワード4.7. ルールテンプレートの例4.8. データ定義セル4.9. ルールテーブルの列4.10. ルールセットのエントリ4.11. ルールセットエリアのエントリ4.12. ルールセットエリアのルール属性エントリ4.13. RULETABLE のセル4.14. 列タイプ4.15. ルールテーブルの列ヘッダー4.16. 条件の要素4.17. ACTION ステートメント4.18. METADATA ステートメント4.19. セルデータ補間の例4.20. セル内での作業する際のヒント4.21. SPREADSHEETCOMPILER クラス4.22. スプレッドシートベースの決定表の使用4.23. LISTS4.24. 改訂管理4.25. 表形式のデータソース4.26. ルールテンプレートの機能4.27. ルールテンプレートの例4.28. ルールテンプレートの実行4.29. CHANGESET の展開例4.30. CHANGESET およびディレクトリの例4.31. ナレッジエージェント4.32. ナレッジエージェントの例4.33. KNOWLEDGEAGENT オブジェクト4.34. ポーリングサービスの開始4.35. KNOWLEDGEBUILDER 向けのカスタムの CLASSLOADER4.36. KNOWLEDGEBASE CLASSLOADER の再利用4.37. KNOWLEDGEAGENTCONFIGURATION の例4.38. NEWINSTANCE プロパティ4.39. NEWINSTANCE プロパティの使用

282929292930303031323233

35353535363636363838393940414141424344444445454545454646474848484949494950505050

JBoss Rules 5 リファレンスガイドリファレンスガイド

2

Page 7: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4.40. NEWINSTANCE の例4.41. リモートの HTTP リソースキャッシュ4.42. 再起動後のリソースキャッシュのリストア

第第5章章 処理処理5.1. アジェンダ5.2. アジェンダの処理5.3. デフォルトの競合解消戦略5.4. AGENDAGROUP5.5. SETFOCUS()5.6. SETFOCUS() の例5.7. ACTIVATIONGROUP5.8. ACTIVATIONGROUP の例5.9. RULEFLOWGROUP5.10. RULEFLOWGROUP の例5.11. ルールとメソッドの違い5.12. クロスプロダクトの例5.13. アクティベーション、アジェンダ、コンフリクトの例5.14. 競合解消戦略5.15. 競合解消戦略の例5.16. トリガーの例5.17. RULEFLOW-GROUP の例5.18. 推論の例5.19. 推論および TRUTHMAINTENANCE の実装

第第6章章 ルール言語ルール言語6.1. KNOWLEDGEBUILDER6.2. RESOURCEFACTORY6.3. 新しい KNOWLEDGEBUILDER の作成6.4. DRL リソースの追加6.5. KNOWLEDGEBUILDER 結果の確認方法6.6. KNOWLEDGEPACKAGES の取得6.7. KNOWLEDGEBUILDER の展開例6.8. バッチモードでの KNOWLEDGEBUILDER の使用6.9. 最後に追加した DRL ビルドの破棄6.10. 設定および CHANGESET XML を使用した構築6.11. CHANGESET XML の XML スキーマ (標準ではない)

第第7章章 CHANGESET7.1. CHANGESET7.2. CHANGESET の例7.3. CHANGESET XML の例7.4. CHANGESET プロトコル7.5. CHANGESET XML のロード7.6. リソース設定を持つ CHANGESET XML の例7.7. CHANGESET XML およびディレクトリ

第第8章章 構築構築8.1. ビルド結果の重要度8.2. デフォルトのビルド結果の重要度設定8.3. KNOWLEDGEPACKAGE8.4. 新しい KNOWLEDGEBASE の作成8.5. インプロセス構築およびデプロイ8.6. KNOWLEDGEBASE への KNOWLEDGEPACKAGES の追加

515151

5252525253535353535354545455565757575858

606060606061616262626363

6565656566666667

68686868696969

目次目次

3

Page 8: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.7. 別のプロセスでの構築およびデプロイメント8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述8.9. INPUTSTREAM から KNOWLEDGEPACKAGE の読み取り8.10. JBOSS RULES 管理システム8.11. STATEFULKNOWLEDGESESSIONS および KNOWLEDGEBASE の変更8.12. 新たな KNOWLEDGEAGENT8.13. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述8.14. スキャンと通知サービスの開始8.15. RESOURCECHANGESCANNER8.16. スキャン間隔の変更8.17. ナレッジエージェントとナレッジベース間の対話8.18. 既存の KNOWLEDGEBASE の使用8.19. APPLYCHANGESET() メソッド8.20. ディレクトリのコンテンツを追加するための CHANGESET XML8.21. KNOWLEDGEAGENTCONFIGURATION プロパティ8.22. スキャン動作の変更

第第9章章 セッションセッション9.1. JBOSS RULES のセッション9.2. KNOWLEDGEBASE からの STATEFULKNOWLEDGESESSION の作成9.3. WORKINGMEMORYENTRYPOINT メソッド9.4. KNOWLEDGERUNTIME インターフェース9.5. ファクトの挿入9.6. FACTHANDLE トークン9.7. FACTHANDLE の例9.8. アイデンティティと等価9.9. 取り消し9.10. 取り消しの例9.11. UPDATE() メソッド9.12. UPDATE() の例9.13. クエリ9.14. クエリの例9.15. ライブクエリ9.16. VIEWCHANGEDEVENTLISTENER の実装例9.17. KNOWLEDGERUNTIME

第第10章章 オブジェクトとインターフェースオブジェクトとインターフェース10.1. グローバル (GLOBAL)10.2. GLOBAL との連携10.3. GLOBAL の解決10.4. SESSION SCOPED GLOBAL の例10.5. STATEFULRULESESSIONS10.6. AGENDAFILTER オブジェクト10.7. AGENDAFILTER の使用10.8. ルールエンジンのフェーズ10.9. イベントモデル10.10. KNOWLEGERUNTIMEEVENTMANAGER10.11. WORKINGMEMORYEVENTMANAGER10.12. AGENDAEVENTLISTENER の追加10.13. ワーキングメモリのイベントの出力10.14. KNOWLEGERUNTIMEEVENTS10.15. KNOWLEDGERUNTIMEEVENT インターフェースに対応のイベント10.16. KNOWLEDGERUNTIMELOGGER

69707070707071717171

727272727373

747474747474747575757576767676777778

7979797980808080808181818182828282

JBoss Rules 5 リファレンスガイドリファレンスガイド

4

Page 9: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10.17. FILELOGGER の有効化10.18. JBOSS RULES での STATELESSKNOWLEDGESESSION の使用10.19. コレクションを使用した STATELESSKNOWLEDGESESSION の実行10.20. INSERTELEMENTS コマンドを使用した STATELESSKNOWLEDGESESSION の実行10.21. BATCHEXECUTIONHELPER10.22. COMMANDEXECUTOR インターフェース10.23. OUT 識別子

第第11章章 モードとメソッドモードとメソッド11.1. シーケンシャルモード11.2. シーケンシャルモードのオプション11.3. シーケンシャルモードの有効化11.4. COMMANDFACTORY11.5. 対応の COMMANDFACTORY オプション11.6. 挿入コマンド11.7. 挿入コマンドの例11.8. 実行メソッド11.9. 実行メソッドの例11.10. BATCHEXECUTION コマンド11.11. FIREALLRULES コマンド11.12. OUT 識別子11.13. OUT 識別子の例11.14. 実行 XML の例11.15. 実行マーシャリングの例11.16. BATCH-EXECUTION とコマンドの例11.17. MARSHALLERFACTORY11.18. マーシャラーの例11.19. マーシャリングのオプション11.20. IDENTITYMARSHALLINGSTRATEGY の例11.21. OBJECTMARSHALLINGSTRATEGYACCEPTOR11.22. CLASSFILTERACCEPTOR の実装11.23. アクセプターを使用した IDENTITYMARSHALLINGSTRATEGY の例11.24. JBOSS RULES の永続性とトランザクション11.25. トランザクション例11.26. JPA の使用11.27. JPA を持つ STATEFULKNOWLEDGESESSION のロード11.28. JPA の設定11.29. JTA DATASOURCE の設定11.30. JNDI プロパティ11.31. KNOWLEDGEBASE 名前空間

第第12章章 USING SPREADSHEET DECISION TABLES12.1. ハードキーワード12.2. ソフトキーワード12.3. ソフトキーワードのリスト12.4. コメント12.5. 1 行コメントの例12.6. 複数行コメントの例12.7. エラーメッセージ12.8. パッケージ12.9. IMPORT ステートメント12.10. GLOBAL の使用12.11. FROM 要素

83838384848484

8686868687878787878888888888898990939393949494949595969696979797

9898989899

100100100101101101102

目次目次

5

Page 10: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12.12. E-メールサービスでの GLOBAL の使用

第第13章章 関数関数13.1. 関数13.2. 関数宣言の例13.3. 静的メソッドを使用する関数宣言の例13.4. 関数宣言呼び出しの例13.5. 型宣言13.6. 型宣言のロール13.7. 新しい型の宣言13.8. 新しいファクト型の宣言例13.9. 新しいファクト型の宣言の追加例13.10. IMPORT の使用例13.11. 生成された JAVA クラス13.12. 生成 JAVA クラスの例13.13. ルールでの宣言型の使用例13.14. メタデータの宣言13.15. メタデータ属性との連携13.16. ファクト型でのメタデータ属性の宣言例13.17. @POSITION 属性13.18. @POSITION の例13.19. 事前定義済みのクラスレベルアノテーション13.20. @KEY 属性関数13.21. @KEY 宣言の例13.22. キーコンストラクターでのインスタンスの作成例13.23. 位置引数13.24. 位置引数の例13.25. @POSITION アノテーション13.26. パターンの例

第第14章章 その他の宣言その他の宣言14.1. 既存のタイプのメタデータの宣言14.2. 既存型へのメタデータの宣言例14.3. 完全修飾クラス名を使用したメタデータの宣言例14.4. 宣言型に対してパラメーター化されたコンストラクトの例14.5. 型安全でないクラス14.6. アプリケーションコードからの宣言済みタイプへのアクセス14.7. 型の宣言14.8. API を使用して宣言されたファクト型を処理する例14.9. 型宣言の EXTENDS14.10. 型宣言の EXTENDS 例14.11. TRAIT14.12. TRAIT の例14.13. コアオブジェクトと TRAIT14.14. @TRAITABLE の例14.15. TRAIT でのルールの記述14.16. TRAIT とルールの例14.17. 隠しフィールド14.18. 二部プロキシ (TWO-PART PROXY)14.19. ラッパー14.20. ラッパーの例14.21. ISA アノテーションを使用したラッパー例14.22. TRAIT の削除

102

103103103103103104104104104105105105105106106106106107107107108108108108109109109

110110110110110111111111111112112112112113113113114114114114114115115

JBoss Rules 5 リファレンスガイドリファレンスガイド

6

Page 11: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14.23. ルール構文の例14.24. タイマー属性の例14.25. タイマー14.26. CRON タイマーの例14.27. カレンダー14.28. QUARTZ カレンダーの例14.29. カレンダーの登録14.30. 左辺部 (LHS)14.31. 条件の要素14.32. 条件要素なしのルールの例

第第15章章 パターンパターン15.1. パターン15.2. パターンの例15.3. パターン一致15.4. パターンのバインディング15.5. 変数でバインドしたパターンの例15.6. 制約

第第16章章 要素と変数要素と変数16.1. JAVA BEAN でのプロパティアクセス (POJO)16.2. POJO の例16.3. POJO との連携16.4. POJO フォールバック16.5. フォールバックの例16.6. JAVA 表現16.7. コンマ区切りの演算子16.8. コンマ区切りの演算子例16.9. バインド変数16.10. バインド変数の例16.11. ユニフィケーション16.12. ユニフィケーションの例16.13. JBOSS RULES のオプションと演算子16.14. 演算子の優先順位16.15. 粒度の高いプロパティ変更リスナー16.16. 粒度の高いプロパティ変更リスナーの例16.17. 粒度の高いプロパティ変更リスナーとの連携16.18. @WATCH でのパターンの使用16.19. @WATCH の例16.20. @PROPERTYSPECIFICOPTION の使用16.21. 基本的な条件要素16.22. 条件要素 FORALL16.23. FORALL の例16.24. 条件要素 FROM16.25. FROM の例16.26. 条件要素 COLLECT16.27. 条件要素 ACCUMULATE16.28. 条件要素 ACCUMULATE の構文16.29. 条件要素 ACCUMULATE の関数16.30. 条件要素 ACCUMULATE およびプラガビリティ16.31. 条件要素 ACCUMULATE とプラガビリティの例16.32. 条件要素 ACCUMULATE 関数のコード16.33. インライン式のカスタムコードを使用した ACCUMULATE

115116116116116117117117117118

119119119119119

120120

121121121121122122122124124124125125125125129129130130130130131131135135136136137138138139139139141142

目次目次

7

Page 12: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16.34. インライン式のカスタムコードを使用した ACCUMULATE の例16.35. 条件要素 EVAL16.36. 条件要素 EVAL の例16.37. 右辺部 (RHS)16.38. RHS コンビニエンスメソッド16.39. DROOLS 変数を使用したコンビニエンスメソッド16.40. KCONTEXT 変数を使用したコンビニエンスメソッド16.41. MODIFY ステートメント16.42. クエリーの例16.43. QUERYRESULTS の例16.44. 他のクエリを呼び出すクエリ16.45. 他のクエリを呼び出すクエリ例16.46. 派生クエリのユニフィケーション

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)17.1. ドメイン固有言語17.2. DSL の使用17.3. DSL の例17.4. DSL パーサーの仕組み17.5. DSL コンパイラー17.6. DSL 構文の例17.7. DSL 表現の連鎖17.8. ファクトへの制約の追加17.9. DSL 開発のヒント17.10. DSL および DSLR 参照17.11. DSL エントリの構成17.12. DSL 拡張のデバッグオプション17.13. DSL 定義の例17.14. DSLR ファイルの変換17.15. 文字列変換関数17.16. 文字列 DSL 変換関数

第第18章章 XML18.1. XML 形式18.2. XML ルールの例18.3. XML 要素18.4. ルール要素の詳細18.5. XML ルールの要素18.6. XML と DRL 間の自動変換18.7. XML と DRL 間の自動変換用のクラス

第第19章章 JAVA ルールエンジンアプリケーションプログラミングインターフェースルールエンジンアプリケーションプログラミングインターフェース19.1. JSR9419.2. JAVAX.RULES インターフェース19.3. JAVAX.RULES クラス19.4. JAVAX.RULES の例外19.5. ルールサービスプロバイダーの使用19.6. JAVAX.RULES.ADMIN インターフェース19.7. JAVAX.RULES.ADMIN の例外19.8. RULESERVICEPROVIDER19.9. RULESERVICEPROVIDERMANAGER19.10. RULESERVICEPROVIDER 自動登録の例19.11. LOCALRULEEXECUTIONSET を RULEADMINISTRATOR API で登録19.12. ステートフルおよびステートレス RULESESSIONS

143144144144144145146146147148148148149

150150150150150151151153153155156156156157157158159

161161161165165166167167

168168168169170170171171171

172172172173

JBoss Rules 5 リファレンスガイドリファレンスガイド

8

Page 13: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19.13. JSR94 での GLOBAL の使用19.14. JSR94 で GLOBAL を使用した例19.15. JSR94 に関する参考資料

第第20章章 JBOSS DEVELOPER STUDIO20.1. ルールの統合開発環境 (IDE)20.2. RULES IDE 機能20.3. JBOSS RULES ランタイム20.4. JBOSS RULES ランタイムの定義20.5. JBOSS RULES プロジェクトに対するランタイムの選択20.6. RULE ファイルの例20.7. JBOSS RULES BUILDER20.8. 新規ルールの作成20.9. ルールエディター20.10. JBOSS ルールビュー20.11. JBOSS RULES ビューの使用20.12. SHOW LOGICAL STRUCTURE20.13. 監査ログの作成20.14. 監査ビューのイベントアイコン20.15. 原因取得のメソッド20.16. DSL エディター20.17. ルール言語マッピング20.18. ルール言語マッピングでの作業20.19. DSL 変換コンポーネント20.20. 大きな DRL ファイルで作業する際のヒント20.21. ブレークポイントの作成20.22. JBOSS RULES アプリケーションとしてのデバッグ20.23. RULES IDE の設定

第第21章章 HELLO WORLD の例の例21.1. HELLOWORLD の例: KNOWLEDGEBASE とセッションの作成21.2. HELLOWORLD の例: イベントのロギングと監査21.3. HELLOWORLD の例: MESSAGE クラス21.4. HELLOWORLD の例: 実行21.5. HELLOWORLD の例: コンソールウィンドウでの SYSTEM.OUT21.6. HELLOWORLD の例: ルール "HELLO WORLD"21.7. HELLOWORLD の例: "DEBUG AS..." オプションの使用21.8. HELLOWORLD の例: ルール "GOOD BYE"

第第22章章 SALIENCE ステータスの例ステータスの例22.1. SALIENCE ステータスの例: STATE クラスの例22.2. SALIENCE ステータスの例: 実行22.3. SALIENCE ステータスの例: アプリケーションの実行22.4. SALIENCE ステータスの例: オペレーションのある監査ロギングを使用22.5. SALIENCE ステータスの例: ルール "BOOTSTRAP"22.6. SALIENCE ステータスの例: ルール "B TO C"22.7. SALIENCE ステータスの例: ルール "B TO D"22.8. SALIENCE ステータスの例: 動的ファクトの挿入22.9. SALIENCE ステータスの例: PROPERTYCHANGESUPPORT を持つセッター22.10. SALIENCE ステータスの例: グループルール "B TO C"22.11. SALIENCE ステータスの例: グループルール "B TO D"22.12. SALIENCE ステータスの例: グループルール "D TO E"

第第23章章 フィボナッチの例フィボナッチの例

174174175

177177177177178178179179179180180181181181182182183183183183184184185185

187187187188188189190190190

192192192192193193194194194195195196196

198

目次目次

9

Page 14: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23.1. フィボナッチの例: クラス23.2. フィボナッチの例: 実行23.3. フィボナッチの例: 実行の詳細23.4. FIBONACCI の例: RECURSE ルール23.5. FIBONACCI の例: BOOTSTRAP ルール23.6. FIBONACCI の例: CALCULATE ルール

第第24章章 バンキングの例バンキングの例24.1. バンキングの例: RULERUNNER24.2. バンキングの例: EXAMPLE1.DRL のルール24.3. バンキングの例: JAVA の例 224.4. バンキングの例: EXAMPLE2.DRL のルール24.5. バンキングの例: EXAMPLE3.JAVA24.6. バンキングの例: EXAMPLE3.DRL のルール24.7. バンキングの例: CASHFLOW クラス24.8. バンキングの例: EXAMPLE4.JAVA24.9. バンキングの例: SIMPLEDATE クラス24.10. バンキングの例: EXAMPLE4.DRL のルール24.11. バンキングの例: TYPEDCASHFLOW クラス24.12. バンキングの例: EXAMPLE5.JAVA24.13. バンキングの例: ACCOUNT クラス24.14. バンキングの例: ALLOCATEDCASHFLOW クラス24.15. バンキングの例: EXAMPLE5.JAVA の継承24.16. バンキングの例: EXAMPLE6.DRL のルール

第第25章章 価格設定ルールの例価格設定ルールの例25.1. 価格設定ルールの例: 価格設定ルールの実行例25.2. 価格設定ルールの例: 決定テーブルの設定25.3. 価格設定ルールの例: 基本価格の算出例25.4. 価格設定ルールの例: 割引の算出例

第第26章章 ペットショップの例ペットショップの例26.1. ペットショップの例26.2. ペットショップの例: PETSTORE.MAIN での PETSTORE RULEBASE 作成26.3. ペットショップの例: CHECKOUTCALLBACK.CHECKOUT() からのルールの発火26.4. ペットショップの例: PETSTORE.DRL からのパッケージ、インポート、グローバル、方言26.5. ペットショップの例: PETSTORE.DRL からの抽出された JAVA 関数26.6. ペットショップの例: PETSTORE.DRL からワーキングメモリへのアイテム追加26.7. ペットショップの例: PETSTORE.DRL から GUI のアイテムを表示26.8. ペットショップの例: PETSTORE.DRL からのアジェンダグループの評価26.9. ペットショップの例: PETSTORE.DRL からチェックアウトを抽出26.10. ペットショップの例: PETSTORE.DRL からチェックアウトルール26.11. ペットショップの例: PETSTORE.JAVA の実行26.12. ペットショップの例: チェックアウトルールの実行

第第27章章 数独の例数独の例27.1. 数独の例: 例の読み込み27.2. 数独の例: 壊れた内容のデバッグ例27.3. 数独の例: JAVA ソースおよびルール27.4. 数独の例: CELL オブジェクト27.5. 数独の例: クラスとオブジェクト27.6. 数独の例: VALIDATE.DRL27.7. 数独の例: SUDOKU.DRL

198198199199

200200

202202202203203204204205206206206207208209209210211

214214214215216

218218218219

220220221222222224224225226

227227228228229229229229

JBoss Rules 5 リファレンスガイドリファレンスガイド

10

Page 15: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

第第28章章 数字当ての例数字当ての例28.1. 数字当ての例: サンプルの読み込み28.2. 数字当ての例: RULEFLOW の開始28.3. 数字当ての例: クラスとメソッド28.4. 数字当ての例: RULEFLOW の確認28.5. 数字当ての例: RULEFLOW ノード28.6. 数当ての例: NUMBERGUESS.DRL の特定のポイントでのルールの発火28.7. 数字当ての例: RULEFLOW の制約の確認28.8. 数字当ての例: コンソールの出力

付録付録A 改訂履歴改訂履歴

231231231232232232233234234

236

目次目次

11

Page 16: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

前書き

JBoss Rules 5 リファレンスガイドリファレンスガイド

12

Page 17: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第1章 はじめに

1.1. 対象読者

本書は、JBoss Rules のツールの使用方法を学習したいシステム管理者を対象としています。新規プロジェクトの作成、プロジェクトのデバッグ、エディターの使用方法について説明しています。

バグを報告する

1.2. 本書の目的

本書は、JBoss Rules の使用方法に関する概要を説明することを目的としています。また、基本用語を詳しく説明するとともに、1 からルールを作成する方法も説明しています。プロジェクトのルール作成を支援するチュートリアルも複数含まれています。

バグを報告する

第第1章章 はじめにはじめに

13

Page 18: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第2章 クイックスタート

2.1. JBOSS RULES

JBoss Rules は、JBoss Enterprise SOA Platform 製品に同梱されているビジネルルールエンジンの名称です。

バグを報告する

2.2. JBOSS RULES エンジン

JBoss Rules エンジンは、ルールを適用して知識表現と推論 (KRR: Knowledge Representation andReasoning) 機能を開発者に提供するコンピュータープログラムです。

バグを報告する

2.3. プロダクションルール

プロダクションルールは、二部構成となっており、ナレッジの表現に一階論理を使用します。このルールは、以下の形式を取ります。

バグを報告する

2.4. 推論エンジン

推論エンジンは、JBoss Rules エンジンに含まれているエンジンで、プロダクションのファクトとデータをルールと照合します。その後、情報からの推測をもとにアクションを実行します。プロダクションルールシステムの推論エンジンはステートフルで、真理維持を行います。

バグを報告する

2.5. RETEOO

JBoss Rules で使用される Rete 実装は、ReteOO と呼ばれ、オブジェクト指向システム向けに Rete アルゴリズムを拡張、最適化した実装です。

バグを報告する

2.6. プロダクションメモリ

プロダクションメモリプロダクションメモリとは、ルールを保存する場所のことです。

バグを報告する

2.7. ワーキングメモリ

ワーキングメモリワーキングメモリは、JBoss Rules エンジンの一部でファクトがアサートされるところです。ここか

when <conditions>then <actions>

JBoss Rules 5 リファレンスガイドリファレンスガイド

14

Page 19: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ら、ファクトを変更または削除することができます。

バグを報告する

2.8. 競合解消 (CONFLICT RESOLUTION) 戦略

競合解消は、アジェンダに複数のルールがある場合に必要です。ルールを発火 (fire) すると、ワーキングメモリに悪影響が及ぶ可能性があるため、ルールエンジンはルールを発火する順番を把握しておく必要があります (例えば、ルール A を発火するとルール B がアジェンダから削除されてしまう可能性があるなど)。

バグを報告する

2.9. ハイブリッドルールシステム

ハイブリッドルールシステムは、前向き連鎖と後向き連鎖の両方を使用してルールを処理します。

バグを報告する

2.10. 前向き連鎖

前向き連鎖はプロダクションルールのシステムのことです。前向き連鎖は、渡されたデータに反応するデータ駆動型となっています。ファクトがワーキングメモリに挿入され、1 つまたは複数のルールがtrue となります。その後、アジェンダで実行されるようにスケジュールに設定されます。

JBoss Rules は前向き連鎖エンジンです。

バグを報告する

2.11. 後向き連鎖

後向き連鎖のルールシステムは結論駆動型で、システムはエンジンが充足しようとする結論から開始します。結論を充足できない場合、サブゴール (現在のゴールの一部を完結する結論) を探します。このプロセスは、最初の結論が充足されるか、充足されていないサブゴールがなくなるまで継続します。Prolog は後向き連鎖エンジンの一例になります。

重要重要

後向き連鎖は、JBoss BRMS 5.2 で実装されました。

バグを報告する

2.12. 推論機能

JBoss Rules は、後向き連鎖の推論機能を使用してデータからどのルールを適用するかを推論しやすくします。

バグを報告する

2.13. エキスパートシステム

第第2章章 クイックスタートクイックスタート

15

Page 20: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

エキスパートシステムは、プロダクションルールシステムというフレームワークでドメインを表現するためのオントロジモデルを使用して、ナレッジの獲得や説明の機能を含めることで形成されると言われています。

バグを報告する

2.14. RETE ROOT ノード

Rete 00 を使用する場合、全オブジェクトがネットワークに入る場所が root ノードとなっています。ここから、ObjectTypeNode にすぐ移動します。

バグを報告する

2.15. OBJECTTYPENODE

ObjectTypeNode は、ルールエンジンのワークロードを減らすのに役立ちます。オブジェクトが複数あり、ルールエンジンがオブジェクト毎にノードを 1 つずつ評価しようとする場合、多くのサイクルが無駄になります。効率化を図るため、ObjectTypeNode を使用してエンジンがオブジェクトの型に合うノードにのみオブジェクトを渡すようにします。こうすることで、アプリケーションが新しいアカウントをアサートしても、Order オブジェクトにはこのノードは伝播されません。

JBoss Rules では、アサートされたオブジェクトは、HashMap のルックアップを利用して有効なObjectTypesNodes の一覧をオブジェクトのクラスから取得します。この一覧が存在しない場合、ObjectTypeNodes のをすべてスキャンして、マッチする有効な結果を探し出し一覧にキャッシュします。こうすることで、instanceof チェックとマッチするクラス型はどれでも JBoss Rules で照合することができるようになります。

バグを報告する

2.16. ALPHANODES

AlphaNodes は、リテラル条件を評価する際に使用します。1 つのオブジェクト型に対して複数のリテラル条件がルール内に含まれる場合、これらのリテラル条件は関連付けられます。つまり、アプリケーションがアカウントオブジェクトをアサートした場合、最初のリテラル条件を充足してからでないと次の AlphaNode に進むことができなくなっています。

AlphaNodes は ObjectTypeNodes で伝播されます。

バグを報告する

2.17. ハッシュ

JBoss Rules は ObjectTypeNode から AlphaNode への伝播を最適化することでハッシュを使用してRete を拡張します。AlphaNode が ObjectTypeNode に追加されるたびに、キーとしてのリテラル値を、値として AlphaNode を持つ HashMap に追加します。新しいインスタンスが ObjectType ノードに入ると、各 AlphaNode に伝播せずに HashMap から正しい AlphaNode を取得して、必要のないリテラルチェックを回避します。

バグを報告する

2.18. BETANODES

BetaNodes は、2 つのオブジェクトとそのフィールドを比較する際に使用します。これらのオブジェクトの型は、同じ場合も、違う場合もあります。

JBoss Rules 5 リファレンスガイドリファレンスガイド

16

Page 21: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

2.19. アルファメモリ

アルファメモリは、BetaNode への右からの入力を指します。JBoss Rules では、この入力により、入ってきたオブジェクトをすべて記憶します。

バグを報告する

2.20. ベータメモリ

ベータメモリは、BetaNoe の左側の入力を指します。このメモリは、入ってくるタプルをすべて記憶します。

バグを報告する

2.21. BETANODES を用いたルックアップ

ファクトが片方から入った場合、ハッシュルックアップを行い有効な候補を返します (インデックス)。どの時点であっても有効な結合が見つかった場合は、タプルはオブジェクトと結合して (一部合致)、次のノードに伝播します。

バグを報告する

2.22. LEFTINPUTNODEADAPTERS

LeftInputNodeAdapter は、オブジェクトを入力として受け入れ、1 つのオブジェクトタプルとして伝播します。

バグを報告する

2.23. 終端ノード

終端ノードは、ある単一ルールが全条件に合致したこと (つまり、ルールに完全合致があったこと) を示すのに使用します。or 条件の分離結合のあるルールでは、考えられる論理分岐ごとにサブルールが生成されることになります。これにより、1 つのルールに複数の終端ノードを含めることができます。

バグを報告する

2.24. ノード共有

ノード共有は、不必要な冗長性を避けるために使用されます。多くのルールは同じパターンを繰り返すため、ノード共有があるとこのようなパターンを減らして、インスタンスごとに再評価しなくてもよくなります。

バグを報告する

2.25. ノード共有の例

以下では 2 つのルールが最初のパターンを共有していますが、最後のパターンは共有していません。

rule

第第2章章 クイックスタートクイックスタート

17

Page 22: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

2.26. 疎結合

疎結合は、ルール同士を緩く関連付け、1 つのルールが実行されても別のルールが実行されないようにします。

一般的に、より柔軟性のある疎結合の設計が推奨されます。ルールがすべて密結合されている場合、柔軟性に欠けることが多くなります。さらに、このような状況でのルールエンジンのデプロイは過剰対応であることが分かります。

バグを報告する

2.27. 密結合

密結合は、ルールを関連付ける方法の 1 つです。ルールが密結合されている場合、1 つのルールを実行すると他の実行が引き起こされることになります。つまり、明確な論理的つながりがあるということです (明確な連鎖は、決定木を使用してハードコード化するか、実装することができます)。

バグを報告する

2.28. 宣言型プログラミング

宣言型プログラミングは、「どのようにするか」ではなく「何をするか」をルールエンジンが宣言できるように手段を指します。宣言プログラミングの主な利点は、ルールを使用すると困難な問題に対して解決策を簡単に提示でき、結果的にこれらの解決策を検証できます。また、ルールはコードを解読するよりもはるかに簡単です。

バグを報告する

2.29. 論理とデータの分離

論理とデータの分離は、論理とデータのコンポーネントの結合を切り離すプロセスのことです。この手法を使用して、論理を多数のドメインオブジェクトやコントローラーに展開し、1 つまたは複数の分離ルールファイルですべてを整理することができます。

バグを報告する

when vehicle( $car : name == "car" ) $driver: Driver( typeCar == $sedan )then System.out.println( $driver.getName() + " drives sedan" );end

rulewhen Vehicle( $sedan : name == "sedan" ) $driver : Driver( typeCar != $sedan )then System.out.println( $driver.getName() + " does not drive sedan" );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

18

Page 23: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2.30. ナレッジベース

ナレッジベースは、KnowledgeBuilder でコンパイルされたルールの集まりで、アプリケーションのナレッジ定義すべてに対するレポジトリでもあります。ナレッジベースには、ルール、プロセス、関数、型モデルなどが含まれている場合があります。ナレッジベース自体には、(ファクトとして知られる) インスタンスデータは含まれておらず、代わりに、データの挿入やプロセスインスタンスの開始が可能なナレッジベースからセッションが作成されます。セッションの作成を繰り返し行えるように、ナレッジベースをキャッシュできるようにすることが推奨されます。

バグを報告する

第第2章章 クイックスタートクイックスタート

19

Page 24: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第3章 ユーザーガイド

3.1. ステートレスナレッジセッション

ステートレスナレッジセッションは、推論なしのセッションのことです。ステートレスセッションは、セッションを使用してデータを渡し、結果を再度受け取るという点から関数のようであると言われます。

ステートレスナレッジセッションは、バリデーション、演算、ルーティング、フィルタリングを必要とする場合に便利です。

バグを報告する

3.2. ステートレスセッションでのルールの設定

手順手順3.1 タスクタスク

1. 以下の運転免許証の例のようにデータモデルを作成します。

2. 最初のルールを記述していきます。この例では、18 歳未満の申請者を拒否するためのルールを追加しています。

3. Applicant オブジェクトがルールエンジンに挿入されると、各ルールの制約がそのオブジェクトを評価して一致があるか検索します (「オブジェクト型」には常に暗黙的な制約があり、それ以降は明示的なフィールド制約をいくつでも存在させることができます)。

Is of valid age ルールでは、以下の 2 つの制約があります。

一致するファクトは、Applicant 型である必要があります。

Age の値は 18 未満である必要があります。

$a はバインド変数で、これを設定することで、ルールの結果 (ここからオブジェクトのプロパティを更新可能) 内の一致オブジェクトへ参照ができるようになります。

public class Applicant { private String name; private int age; private boolean valid; // getter and setter methods here}

package com.company.license

rule "Is of valid age"when $a : Applicant( age < 18 )then $a.setValid( false );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

20

Page 25: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

ドル記号 ($) の使用はオプションです。これを使用すると、変数名とフィールド名を区別できます。

注記注記

ルールがクラスと同じフォルダー内にある場合、クラスパスのリソースローダーを使用して最初のナレッジベースを構築することができます。

4. 以下のように、KnowledgeBuilder を使用してルール一覧をナレッジベースにコンパイルします。

上記のコードスニペットは、newClassPathResource() メソッドを使用して、クラスパス内の licenseApplication.drl ファイルを検索します (リソースのタイプは Drools ルール言語 (DRL: Drools Rule Language) です)。

5. KnowledgeBuider にエラーがないか確認してください。エラーがない場合は、セッションを構築できます。

6. ルールに対してデータを実行します (申請者は 18 歳未満であるため、申請は「無効」とマークされます)。

結果結果

先ほどのコードは、ルールに対してデータを実行しました。申請者が 18 歳未満であるため、この申請は無効とマークされました。

バグを報告する

3.3. 複数のオブジェクトを使用したルールの設定

手順手順3.2 タスクタスク

1. オブジェクト実装 iterable (コレクションなど) に対してルールを実行するには、以下のコードサンプルに記載しているように別のクラスを追加します。

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newClassPathResource( "licenseApplication.drl", getClass() ), ResourceType.DRL );if ( kbuilder.hasErrors() ) { System.err.println( kbuilder.getErrors().toString() );}KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();Applicant applicant = new Applicant( "Mr John Smith", 16 );assertTrue( applicant.isValid() );ksession.execute( applicant );assertFalse( applicant.isValid() );

第第3章章 ユーザーガイドユーザーガイド

21

Page 26: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. 申請が正規の時間枠内に行われたことを確認するために、以下のルールを追加します。

3. JDK コンバーターを使用して、iterable インターフェースを実装します (このメソッドは Arrays.asList(...) という行で始まります)。以下のコードは、iterable リストに対してルールを実行しています。全コレクション要素は、一致するルールが発火される前に挿入されます。

注記注記

実は、execute(Object object) と execute(Iterable objects) メソッドは、 BatchExecutor インターフェースからの execute(Command command) と呼ばれる別のメソッドの周りにある「ラッパー」です。

4. CommandFactory を使用して指示を作成し、以下が execute( Iterable it ) と同じになるようにします。

public class Applicant { private String name; private int age; // getter and setter methods here}

public class Application { private Date dateApplied; private boolean valid; // getter and setter methods here}

package com.company.license

rule "Is of valid age"when Applicant( age < 18 ) $a : Application() then $a.setValid( false );end

rule "Application was made this year"when $a : Application( dateApplied > "01-jan-2009" ) then $a.setValid( false );end

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();Applicant applicant = new Applicant( "Mr John Smith", 16 );Application application = new Application();assertTrue( application.isValid() );ksession.execute( Arrays.asList( new Object[] { application, applicant } ) );assertFalse( application.isValid() );

JBoss Rules 5 リファレンスガイドリファレンスガイド

22

Page 27: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

5. 違うコマンドや結果出力の識別子を多数使用する場合は、BatchExecutor と CommandFactory を使用します。

注記注記

CommandFactory は、BatchExecutor で使用可能な他のコマンドを多数サポートしています。例えば、StartProcess、Query、SetGlobal などです。

バグを報告する

3.4. ステートフルセッション

ステートフルセッションは、反復的な変更をファクトに継続して加えることができます。StatelessKnowledgeSession では、StatefulKnowledgeSession は BatchExecutor インターフェースをサポートしています。唯一の相違点は、最後に FireAllRules コマンドが自動的に呼び出されない点です。

警告警告

必ず、dispose() メソッドは、ステートフルセッションの実行後に呼び出すようにしてください。こうすることで、メモリリークが確実になくします。これは、ナレッジベースの作成時にナレッジベースがステートフルナレッジセッションへの参照を取得するのが原因です。

バグを報告する

3.5. ステートフルセッションセッションの一般的なユースケース

モニタリングモニタリング

例えば、株式市場の監視や購入プロセスの自動化が可能です。

診断診断

ksession.execute( CommandFactory.newInsertIterable( new Object[] { application, applicant } ) );

List<Command> cmds = new ArrayList<Command>();cmds.add( CommandFactory.newInsert( new Person( "Mr John Smith" ), "mrSmith" );cmds.add( CommandFactory.newInsert( new Person( "Mr John Doe" ), "mrDoe" );BatchExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) );assertEquals( new Person( "Mr John Smith" ), results.getValue( "mrSmith" ) );

第第3章章 ユーザーガイドユーザーガイド

23

Page 28: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ステートフルセッションは、障害検出プロセスを実行するために使用できます。また、医療診断プロセスでも利用可能です。

輸送関係輸送関係

例えば、小包追跡や配送提供に関する問題にも適用できます。

コンプライアンスの確保コンプライアンスの確保

例えば、市場取引の合法性を検証するために使用できます。

バグを報告する

3.6. ステートフルセッションの監査の例

手順手順3.3 タスクタスク

1. 監査対象のモデルを作成します。火災報知に関するこの例では、家の中の部屋がリストアップされています。各部屋にはスプリンクラーがあり、火災はどの部屋からでも発生する可能性があります。

2. このルールは、(特定の部屋のスプリンクラーの存在などを定義するため) 複数のオブジェクト間の関係を表記する必要があります。これには変数のバインドをパターンの制約として使用します。結果、クロスプロダクトになります。

3. Fire クラスのインスタンスを作成して、セッションに挿入します。

以下のルールは、Fire オブジェクトの room フィールドへバインドを追加して照合条件に制約を加え、その部屋のスプリンクラーのみがチェックされるようにします。このルールが発火して結果が実行されると、スプリンクラーが作動します。

public class Room { private String name // getter and setter methods here}

public class Sprinkler { private Room room; private boolean on; // getter and setter methods here}

public class Fire { private Room room; // getter and setter methods here}

public class Alarm {}

JBoss Rules 5 リファレンスガイドリファレンスガイド

24

Page 29: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ステートレスセッションは標準の Java 構文を使用してフィールドを変更しましたが、上記のルールは modify ステートメントを使用します ("with" ステートメントのように動作します)。

バグを報告する

3.7. 一階論理

一階論理では、個別のインスタンスではなくデータセットを参照することができます。

バグを報告する

3.8. 一階論理を使ったルール設定

手順手順3.4 タスクタスク

1. キーワード Not で特徴づけられるパターンを設定します。一階論理は、他のキーワードがない場合にのみルールの照合が行われるようにします。この例でのルールは、鎮火されるとスプリンクラーをオフにします。

2. Alarm オブジェクトは、火災発生時に作成されますが、火災の数に関係なく建物全体で必要な Alarm は 1 つのみです。Not の補完である exists を使用できるようになりました。これは、カテゴリの 1 つまたは複数のインスタンスとマッチします。

rule "When there is a fire turn on the sprinkler"when Fire($room : room) $sprinkler : Sprinkler( room == $room, on == false )then modify( $sprinkler ) { setOn( true ) }; System.out.println("Turn on the sprinkler for room "+$room.getName());end

rule "When the fire is gone turn off the sprinkler"when $room : Room( ) $sprinkler : Sprinkler( room == $room, on == true ) not Fire( room == $room )then modify( $sprinkler ) { setOn( false ) }; System.out.println("Turn off the sprinkler for room "+$room.getName());end

rule "Raise the alarm when we have one or more fires"when exists Fire()then insert( new Alarm() ); System.out.println( "Raise the alarm" );end

第第3章章 ユーザーガイドユーザーガイド

25

Page 30: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

3. すべて鎮火された場合はアラームを解除する必要があります。アラームをオフにするには Notを使用します。

4. このこーをを使用して、アプリケーションの初回起動時、アラームの解除時、全スプリンクラーの解除時に一般的なヘルスステータスのメッセージを出力します。

5. fireAlarm.drl と呼ばれるファイルにルールを格納して、このファイルをクラスパスのサブディレクトリに保存します。

6. 最後に、新しい名前 fireAlarm.drl を使用して、knowledge base をビルドします。

バグを報告する

3.9. ルールシステムの設定サンプル

手順手順3.5 タスクタスク

1. ksession.fireAllRules() を挿入します。これにより、合致するルールの実行パーミッションを割り当てましたが、この例では火災が起こっていないため、ヘルスメッセージのみを生成します。

rule "Cancel the alarm when all the fires have gone"when not Fire() $alarm : Alarm()then retract( $alarm ); System.out.println( "Cancel the alarm" );end

rule "Status output when things are ok"when not Alarm() not Sprinkler( on == true ) then System.out.println( "Everything is ok" );end

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newClassPathResource( "fireAlarm.drl", getClass() ), ResourceType.DRL ); if ( kbuilder.hasErrors() ) System.err.println( kbuilder.getErrors().toString() );

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

String[] names = new String[]{"kitchen","bedroom","office","livingroom"};Map<String,Room> name2room = new HashMap<String,Room>();

JBoss Rules 5 リファレンスガイドリファレンスガイド

26

Page 31: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

結果として出力されるメッセージは以下のとおりです。

> Everything is okay

2. 火災を 2 つ作成、挿入します (ファクトハンドルは保持されます)。

3. エンジンに火災があるため、fireAllRules() を呼び出します。火災報知機が作動して、該当するスプリンクラーがオンになります。

結果として出力されるメッセージは以下のとおりです。

> Raise the alarm> Turn on the sprinkler for room kitchen> Turn on the sprinkler for room office

4. 鎮火すると火災オブジェクトが取り消され、スプリンクラーがオフになります。この時点で火災報知器はキャンセルされ、ヘルスメッセージがもう一度表示されます。

結果として出力されるメッセージは以下のとおりです。

> Turn off the sprinkler for room office> Turn off the sprinkler for room kitchen> Cancel the alarm> Everything is okay

バグを報告する

3.10. JBOSS RULES のメソッド

for( String name: names ){ Room room = new Room( name ); name2room.put( name, room ); ksession.insert( room ); Sprinkler sprinkler = new Sprinkler( room ); ksession.insert( sprinkler );}

ksession.fireAllRules();

Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );Fire officeFire = new Fire( name2room.get( "office" ) );

FactHandle kitchenFireHandle = ksession.insert( kitchenFire );FactHandle officeFireHandle = ksession.insert( officeFire );

ksession.fireAllRules();

ksession.retract( kitchenFireHandle );ksession.retract( officeFireHandle );

ksession.fireAllRules();

第第3章章 ユーザーガイドユーザーガイド

27

Page 32: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

メソッドはルールとは違います。メソッドは直接呼び出され、個別のインスタンスを渡すために使用されます。呼び出しが 1 つの場合は、実行数も 1 つとなります。

バグを報告する

3.11. メソッドの例

メソッドは、以下のように記述されます。

バグを報告する

3.12. ルールの例

ルールは以下のように記述されます。

バグを報告する

3.13. クロスプロダクト

2 つ以上のデータセットを組み合わせた場合、その結果はクロスプロダクトと呼ばれます。

バグを報告する

3.14. クロスプロダクトの制約

手順手順3.6 タスクタスク

ルールが大量のクロスプロダクトを出力しないように、クロスプロダクト自体を制約する必要があります。以下のような変数制約を使用して、クロスプロダクトの制約を行います。

public void helloWorld(Person person) { if ( person.getName().equals( "Chuck" ) ) { System.out.println( "Hello Chuck" ); }}

rule "Hello World" when Person( name == "Chuck" ) then System.out.println( "Hello Chuck" );end

rulewhen $room : Room() $sprinkler : Sprinkler( room == $room )then System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

28

Page 33: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

以下の出力が表示されます。

結果結果

4 行のみの出力で、部屋ごとに正しいスプリンクラーが表示されます。この変数がないと、Room テーブルの行と、Sprinkler テーブルの行が結合され、結果、行が多数出力されることになります。

バグを報告する

3.15. 推論エンジン

推論エンジンは、JBoss Rules エンジンに含まれているエンジンで、プロダクションのファクトとデータをルールと照合します。その後、情報からの推測をもとにアクションを実行します。プロダクションルールシステムの推論エンジンはステートフルで、真理維持を行います。

バグを報告する

3.16. 推論の例

この例では、年齢フィールドと年齢ポリシー制御を行うルールを持つ Person ファクトを使用しています。推論を使用して、Person が成人か未成年かを判断し、その結果に対してアクションを実施します。

上記のスニペットでは、18 歳以上の人には IsAdult というインスタンスが挿入されています。このファクトは特別なもので、「関係」と呼ばれるものです。どのようなルールにおいても、この推論関係を使用することができます。

バグを報告する

3.17. 論理アサーション

標準のオブジェクト挿入の後、明示的にファクトの取り消しを行う必要があります。論理論理アサーションでは、最初にアサートした条件が true でなくなると、アサートされたファクトは自動的に取り消されます。論理アサーションをサポートする単一条件がない場合のみ、取り消されます。

バグを報告する

3.18. 記述 (STATED) 挿入

room:office sprinkler:officeroom:kitchen sprinkler:kitchenroom:livingroom sprinkler:livingroomroom:bedroom sprinkler:bedroom

rule "Infer Adult"when $p : Person( age >= 18 )then insert( new IsAdult( $p ) )end

$p : Person()IsAdult( person == $p )

第第3章章 ユーザーガイドユーザーガイド

29

Page 34: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

通常の挿入は、「ファクトの記述」という意味で記述記述挿入と呼ばれています。HashMap とカウンターを使用して、特定の等価が何回、記述記述されたのかを追跡できます。つまり、同等なインスタンスがいくつあるかカウントすることができます。

バグを報告する

3.19. 正当化 (JUSTIFIED) 挿入

オブジェクトが論理的に挿入されることを正当化 (justified) と呼びます。発火ルールにより正当化されます。各論理挿入に、等価のオブジェクトが 1 つのみあり、それ以降に等価の論理挿入があると、この論理アサーションに対する正当化カウンターの数が増えます。ルールの LHS の作成が true でなくなると正当化が削除され、カウンターの数もそれにあわせて減少します。正当化がなくなると、論理オブジェクトが自動的に取り消されます。

バグを報告する

3.20. WM_BEHAVIOR_PRESERVE 設定

等価の記述記述 (stated) オブジェクトがある場合に論理的に論理的にオブジェクトを挿入すると失敗して null を返します。正当化正当化 (justified) された既存の等価オブジェクトを記述記述するとファクトを上書きすることになります。WM_BEHAVIOR_PRESERVE 設定により、どのように上書きが行われるかが決定します。プロパティが discard に設定されている場合、既存のハンドルを使用して既存のインスタンスが新しいオブジェクトで置き換えられます。これはデフォルトの動作となっています。設定されていない場合は、これを記述記述 (stated) に置き換えてつつも、新しい FactHandle を作成する必要があります。

バグを報告する

3.21. 記述挿入のフローチャート

JBoss Rules 5 リファレンスガイドリファレンスガイド

30

Page 36: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

図図3.1 論理挿入フローチャートのスクリーンショット論理挿入フローチャートのスクリーンショット

バグを報告する

3.23. 真理維持システム

JBoss Rules 真理維持システム (TMS: Truth Maintenance System) とは、信念とナレッジベースにあるその信念に関する依存関係や正当化を表現する方法です。

重要重要

真理維持 (および論理アサーション) を機能させるには、Fact オブジェクトが equals とhashCode メソッドを正しくオーバーライドする必要があります。真理維持システムは、2 つの違った物理オブジェクトが等価であることを把握している必要があるため、Java 規格に従って、equals と hashCode の両方両方を正しくオーバーライドする必要があります。

equals メソッドがそれぞれに true を返し、hashCode メソッドが同じ値を返す場合のみ、2 つのオブジェクトは等価となります。equals と hashCode の両方をオーバーライドする必要があります。

バグを報告する

3.24. INSERTLOGICAL ファクト

insertLogical ファクトは、JBoss Rules TMS の一部です。このファクトは、ルールが状況にあわせて機能して、変更されるように「論理を挿入」します。例えば、insertLogical ファクトはルールセットに追加され、ルールが false になった場合自動的にそのファクトが削除されるようになっています。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

32

Page 37: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

3.25. 推論と TMS の使用

手順手順3.7 タスクタスク

1. この例では、バスの定期券発行のシステムを使用します。以下のコードスニペットを参照してください。

2. 推論を含めるために、insertLogical プロパティを挿入します。

3. コードを再度入力して定期券の発行を行います。TMS は、削除のカスケードセットができるように論理挿入の連鎖に対応しているため、これらの 2 つの設定は論理的に挿入することができます。

その人の (年齢) が 15 から 16 に変わると、IsChild のファクトとその人の ChildBusPass のファクトの両方が自動的に削除されます。

rule "Issue Child Bus Pass" when $p : Person( age < 16 )then insert(new ChildBusPass( $p ) );end rule "Issue Adult Bus Pass" when $p : Person( age >= 16 )then insert(new AdultBusPass( $p ) );end

rule "Infer Child" when $p : Person( age < 16 )then insertLogical( new IsChild( $p ) )endrule "Infer Adult" when $p : Person( age >= 16 )then insertLogical( new IsAdult( $p ) )end

rule "Issue Child Bus Pass" when $p : Person( ) IsChild( person == $p )then insertLogical(new ChildBusPass( $p ) );end rule "Issue Adult Bus Pass" when $p : Person( age >= 16 ) IsAdult( person =$p )then insertLogical(new AdultBusPass( $p ) );end

第第3章章 ユーザーガイドユーザーガイド

33

Page 38: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

4. オプションで、not の条件要素を挿入して通知の処理を行います (この例では定期券の返却依頼についてです)。TMS が自動的に ChildBusPass オブジェクトを削除して、このルールがその人に対する依頼をトリガーして送信します。

バグを報告する

rule "Return ChildBusPass Request "when $p : Person( ) not( ChildBusPass( person == $p ) )then requestChildBusPass( $p );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

34

Page 39: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第4章 決定表

4.1. 決定表

決定表とは、条件論理を表現する手段の 1 つです。決定表は、ビジネスビジネスレベルのルールに非常に適しています。

バグを報告する

4.2. スプレッドシート

JBoss Rules は、スプレッドシート形式でルールを管理します。対応の形式は、Excel (XLS) と CSV です。つまり、様々なスプレッドシートプログラム (Microsoft Excel、OpenOffice.org、Calc など) に対応しています。

バグを報告する

4.3. OPEN OFFICE の例

図図4.1 Open Office のスクリーンショットのスクリーンショット

上記の例では、決定表の技術的な部分は (スプレッドシートの標準機能を使用して) 非表示にしています。

第第4章章 決定表決定表

35

Page 40: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルールは行 17 から始まり、行はそれぞれルールとなります。条件は列 C、D、E などに設定し、アクションは今回は表示されていません。値の意味は、行 16 に記載されています (列 B は (条件ではなく)単なる説明となっています)。

注記注記

決定表は上から順番に処理しているように見えますが、必ずしもそうであるとは限りません。ルールは行の順番など関係なしに作成するのが理想的です。こうすることで、常に行を移動させる必要がないため、メンテナンスが簡単になります。

バグを報告する

4.4. ルールとスプレッドシート

行に挿入されるルール行に挿入されるルール

各行はルールであるため、記述したコードと同じ原則が適用されます。このルールエンジンはファクトを処理するため、合致するルールはすべて発火されます。

アジェンダアジェンダ

ルールが発火され、非常に単純な決定表 (最初に合致したもののみがアクションを引き起こすもの)をシミュレートするとアジェンダが削除されます。

複数の表複数の表

1 つのスプレッドシートに複数のテーブルを含めることができます。こうすることで、共通のテンプレートを共有するルールをグループ化することができます。ただ、これらのルールはすべて、依然として 1 つのルールパッケージに組み込まれています。

バグを報告する

4.5. RULETABLE のキーワード

決定表を使用すると、スプレッドシートはルール表の開始地点を示す RuleTable キーワードを検索します (開始する行と列の両方)。

重要重要

キーワードはすべて同じ列に含まれている必要があります。

バグを報告する

4.6. RULESET キーワード

RuleSet キーワードは、全ルールを含むルールパッケージルールパッケージで使用する名前を指します。デフォルトでは、名前はオプションですが、すぐ右のセルに RuleSet キーワードを設定する必要必要があります。

バグを報告する

4.7. ルールテンプレートの例

JBoss Rules 5 リファレンスガイドリファレンスガイド

36

Page 41: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

図図4.2 ルールテンプレートルールテンプレート

RuleSet キーワードは、全ルールを含むルールパッケージルールパッケージで使用する名前を指します。デフォルトでは、名前はオプションですが、すぐ右のセルに RuleSet キーワードを設定する必要必要があります。C 列に表示されているその他のキーワードは import と Sequential です。

RuleTable キーワードの後には名前が来ますが、この名前は生成されるルールの名前の接頭辞として使用されます。ルール名が必ず一意の名前となるように、行の番号が追加されます。

RuleTable の行は、ルールの開始する行を指します。左側の行は無視されます。

行番号 14 (RuleTable 直後の行) を見てみると、キーワード CONDITION と ACTION は、下の列のデータがルールの LHS 部分または RHS 部分のいずれかに対するものであることが分かります。このようにオプションとしても設定できる他の属性もルールには存在しています。

行番号 15 には、ObjectTypes の宣言が含まれます。この行の内容はオプションですが、このオプションが使用されてない場合、行は空白のままにする必要があります。この行を使用する場合、下のセル (行番号 16) の値はそのオブジェクトタイプに対する制約となります。上記の場合は、Person(age=="42") と Cheese(type=="stilton") (42 と stilton は行番号 18 から来ています) が生成されます。上記の例では、"==" は暗黙的です。フィールド名だけが指定されている場合は、完全一致を生成するように、トランスレーターは推測します。

行番号 16 にはルールテンプレート自体が含まれています。"$param" プレースホルダーを使用して、下のセルからのデータを補間すべき場所を指定することができます (挿入が複数ある場合は "$1"、"$2" などを使用し、下のセルのコンマ区切りの一覧からパラメーターを指定します)。行番号 17 は無視されますが、ここには列の目的に関する説明が記載されている場合があります)。

行番号 18 と 19 はデータを表示します。このデータは、行番号 15 のテンプレートと統合 (補間)され、ルールを生成します。セルにデータが含まれていない場合、そのテンプレートは無視されます (つまり、条件やアクションによってはそのルールの行に該当しないものもあるということです)。ルールの行は、空白の行に到達するまで、読み込まれます。シート内に複数のRuleTables を設置することも可能です。

行番号 20 には別のキーワードや値が含まれます。このように、キーワードの行の位置は関係ありません (大抵の場合は一番上に設定します)。ただし、その列に関しては、RuleTable または RuleSet のキーワードが表示される箇所と同じものでなければなりません。ここでは、列番号 C が選択されていますが、他の列を使用することもできます。

注記注記

ObjectType 宣言は (マージされたセルを使用して) 複数の列をつなげることができます。つまり、同じ ObjectType がマージされていないセルに含まれているものの、最終的に別種/同種のファクトと一部合致するといった別のパターンが出来上がるのではなく、マージされた範囲のすぐ下にある列はすべて、制約セットとして、毎回 1 つのファクトと合致する単一パターンに統合されます。

第第4章章 決定表決定表

37

Page 42: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

上記の例では、ルールは以下のようにレンダリングされます ("ObjectType" 行を使用)。

//row 18rule "Cheese_fans_18"when Person(age=="42") Cheese(type=="stilton")then list.add("Old man stilton");end

注記注記

上記のセルの該当の ObjectType に追加するには、age=="42" と type=="stilton"の制約は 1 つの制約と解釈されます。上記のセルがつながっている場合、1 つの「列」に複数の制約が存在することになります。

警告警告

非常に大きな決定表は、メモリ要件が非常に高くなる可能性があります。

バグを報告する

4.8. データ定義セル

DRL ファイルを生成するために使用する長方形のエリアデータ定義には 2 種類あります。1 つは RuleSet と呼ばれるセルで、ルール以外の DRL アイテムをすべて定義します。もう 1 つは反復して発生して、RuleTable で始まるコンテンツのセルの右および下にあります。これらのエリアは実際の決定表を表しており、各エリアは同様の構造を持つルールを含みます。

RuleSet のエリアにはセルのペアを含めることができ、1 つは RuleSet セルの下にあり、このセルにはもう片方のセル (同じ列で次に来るセル) に含まれる値の種類を指定するキーワードが含まれています。

バグを報告する

4.9. ルールテーブルの列

ルールテーブルエリアの列は、ルールの左側にあるパターンと制約、ルール結果に対するアクション、個別のルール属性の値を定義します。ルールテーブルエリアには、列 1 つ以上、条件とアクション両方、ルール属性に対する任意の選択肢、それぞれに対して最大 1 つの列を含める必要があります。RuleTable というセルの行の後にくる最初の 4 つの行は、ヘッダーエリアとして割り当てられ、多くの場合ルール構築のためのコード定義に使用されます。この 4 つのヘッダー行の下に追加された行で別のルールを生成し、そのデータを使用してルールテーブルヘッダーで定義されているコードのバリエーションを提供します。

JBoss Rules 5 リファレンスガイドリファレンスガイド

38

Page 43: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

キーワードはすべて大文字と小文字の区別をします。

最初のワークシートのみが決定表用に検証されます。

バグを報告する

4.10. ルールセットのエントリ

ルールセットエリアのエントリは、DRL コンストラクト (ルール以外) を定義して、ルール属性を指定することができます。コンストラクトのエントリは繰返し使用して、各ルール属性は最大 1 回指定でき、ルールテーブルエリアで定義された同じ属性により却下されない限りすべてのルールに適用されます。

エントリは、セルのペアを縦に積み上げた順番に指定する必要があります。最初のものにキーワードが、その右側のものに値が含まれます。セルのペアのこの順番は、RuleSet でマークがついた行がキーワードを含むものである限り、空の行またはルールテーブルにより中断可能です。

バグを報告する

4.11. ルールセットエリアのエントリ

表表4.1 ルールセットエリアのエントリルールセットエリアのエントリ

キーワードキーワード 値値 使用法使用法

RuleSet 生成 DRL ファイルのパッケージ名。オプション。デフォルトは rule_table

最初のエントリでなければなりません。

Sequential True または False。True の場合、Salience (優先順位) を使用してルールが上から下へ順番に発火されるようにします。

オプション。最大 1 回。省略されると、発火順が課されます。

EscapeQuotes True または False。True の場合、引用符はエスケープされ、DRL にそのまま表示されるようにします。

オプション。最大 1 回。省略すると、引用符はエスケープされます。

Import インポートする Java クラスのコンマ区切りの一覧

オプション。繰り返し可能

Variables DRL global の宣言。変数名の後にくる型のこと。複数のグローバル定義はコンマで区切る必要があります。

オプション。繰り返し可能

Functions DRL 構文に沿った 1 つまたは複数の関数定義

オプション。繰り返し可能

第第4章章 決定表決定表

39

Page 44: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Queries DRL 構文に沿った 1 つまたは複数の定義

オプション。繰り返し可能

Declare DRL 構文に沿った 1 つまたは複数の宣言型

オプション。繰り返し可能

キーワードキーワード 値値 使用法使用法

バグを報告する

4.12. ルールセットエリアのルール属性エントリ

表表4.2 ルールセットエリアのルール属性エントリルールセットエリアのルール属性エントリ

キーワードキーワード イニシャルイニシャル 値値

PRIORITY P ルールの "salience" 値を定義する整数。"sequential" フラグでオーバーライドされます。

DURATION D ルールの "duration" の値を定義する long 整数値

TIMER T タイマーの定義。"タイマーおよびカレンダー"を参照してください。

CALENDARS E カレンダーの定義。"タイマーおよびカレンダー"を参照してください。

NO-LOOP U ブール値。"true" は、返された結果により変更が加えられたことで発生するルールのループを防止します。

LOCK-ON-ACTIVE L ブール値。"true" は同じルールフローやアジェンダグループ内にこのフラグを設定して、ルールすべてを追加でアクティブ化しないようにします。

AUTO-FOCUS F ブール値。アジェンダグループ内のルールに"true" を設定すると、ルールをアクティブ化して、自動的にこのグループにフォーカスが当たるようにします。

JBoss Rules 5 リファレンスガイドリファレンスガイド

40

Page 45: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ACTIVATION-GROUP X アクティベーション (または XOR)グループを特定する文字列。アクティベーショングループ内のルール 1 つのみが発火されます。最初に発火したルールにより、同じグループ内の他のルールですでにアクティブ化されているものがすべてキャンセルされます。

AGENDA-GROUP G アジェンダグループを特定する文字列。このアジェンダグループはフォーカスを当てることでアクティブ化する必要があり、ルールのグループ間のフローを制御する1 つの方法です。

RULEFLOW-GROUP R ルールフローグループを特定する文字列

キーワードキーワード イニシャルイニシャル 値値

バグを報告する

4.13. RULETABLE のセル

ルールテーブルはすべて、"RuleTable"が含まれているセルから開始され、オプションでその後に同じセル内の文字列が続きます。この文字列は、このルールテーブルから由来のすべてのルールに対する名前の最初の部分として使用されます (このように自動的に指定された名前は、NAME 列を使用して上書きすることができます)。このルールテーブルのルールを定義するその他のセルはすべて、このセルの下または右側に来ることになります。

バグを報告する

4.14. 列タイプ

RuleTable セルの次の行は、列タイプを定義します。各列は、条件または結果の一部となるか、ルール属性、ルール名またはコメントを提供します。各属性列は、1 回まで使用することができます。

バグを報告する

4.15. ルールテーブルの列ヘッダー

表表4.3 ルールテーブルの列ヘッダールールテーブルの列ヘッダー

キーワードキーワード イニシャルイニシャル Value 使用法使用法

第第4章章 決定表決定表

41

Page 46: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

NAME N その行から生成されたルールの名前を提供します。デフォルトは、RuleTable タグと行番号の後にくるテキストから構築されます。

最大 1 列

DESCRIPTION I 生成されたルール内のコメントとなるテキスト。

最大 1 列

CONDITION C 条件内のパターンにある制約を構築するためのコードスニペットおよび補間値

ルールテーブルごとに少なくとも 1 つ

ACTION A ルールの結果に対するアクションを構築するためのコードスニペットおよび補間値

ルールテーブルごとに少なくとも 1 つ

METADATA @ ルールに対するメタデータエントリを構築するためのコードスニペットおよび補間値

オプション。列いくつでも OK

キーワードキーワード イニシャルイニシャル Value 使用法使用法

バグを報告する

4.16. 条件の要素

CONDITION とのヘッダーがついた列の場合、その後の行にあるセルは条件要素となります。

CONDITION の下の最初のセルにあるテキストは、次の行のスニペットが制約となり、ルール条件のパターンへと発展します。セルが周辺のセル 1 つまたは複数とマージされると、複数の制約を持つ 1 つのパターンが形成されます。すべての制約は括弧のリストとなり、このセルのテキストに追加されます。セルは空の状態でも問題ありません。空の場合、次の行のコードスニペットはそれだけで有効な条件要素になります。

制約なしのパターンを含めるには、テキストの前にパターンを記述して別のパターンを作成します。

パターンは、空の括弧ペアの有無に拘らず記述可能です。'from' 句はこのパターンに追加することができます。

パターンが 'eval' で終わる場合、コードスニペットは 'eval' の後の括弧ペアに含めるようにブール値の式を生成するはずです。

CONDITION 配下で 2 番目にくるテキストは、2 段階の手順で処理されます。

1. このセルのコードスニペットは、その列のさらに下にあるセルからの値を補間することで変更します。下のセルからの値と "==" を使用して比較を含む制約を作成する場合、フィールドセレクターだけで十分です。それ以外の比較演算子は、スニペット内の最後のアイテ

JBoss Rules 5 リファレンスガイドリファレンスガイド

42

Page 47: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ムとして指定する必要があり、下のセルからの値は追加されます。その他すべての制約フォームについては、$param のシンボルでセルの内容を含めるために位置を印付けする必要があります。$1、$2 などのシンボルを使用し、下のセルで値をコンマで区切ってリストすることで、複数の挿入も可能です。

パターン forall(delimiter){snippet} に従ったテキストは、配下のセルにあるコンマ区切りの値それぞれに対して 1 回ずつ スニペットスニペットを繰り返して (この際、$ シンボルの場所に値を挿入します)、指定の区切り文字区切り文字でこれらの拡張を結合することで拡張されます。forallコンストラクトは、他のテキストで囲むことができます。

2. 前の行にあるセルが空でない場合、完全なコードスニペットがそのセルから条件要素に追加されます。括弧のペアと、(複数の制約がマージされたセルのパターンに追加されている場合) 区切りコンマが自動的に提供されます。

上のセルが空の場合、補間結果がそのまま使用されます。

CONDITION の 3 つ下のセルのテキストは、例示のみを目的として提示されています。人が解読できるように列の目的を指定するために使用されます。

4 行目以降は、空でないエントリは上記の通り、補間データとして提供されます。空のセルは、このルールの制約や条件要素を省略することになります。

バグを報告する

4.17. ACTION ステートメント

ACTION とのヘッダーがついた列の場合、その後の行にあるセルは Action 要素となります。

ACTION の 1 つ下のセルにあるテキストはオプションです。テキストがある場合、オブジェクト参照して解釈されます。

ACTION 配下で 2 番目にくるテキストは、2 段階の手順で処理されます。

1. このセルのコードスニペットは、その列のさらに下にあるセルからの値を補間することで変更します。挿入が 1 つの場合、$param のシンボルでセルの内容を含めるために位置を印付けします。$1、$2 などのシンボルを使用し下のセルで値をコンマで区切ってリストすることで、複数の挿入も可能です。

マーカーシンボルのないテキストを使うことで、補間なしでメソッドを呼び出すことができます。この場合、配下の行に空でないエントリを使用してステートメントを含めます。

Forall コンストラクトはこちらでも使用できます。

2. 最初のセルが空でない場合、テキスト、その後に来るピリオド、2 番目のセルのテキスト、終わりを示すセミコロンが 1 列に並べられ、メソッドを呼び出して Action ステートメントとして結果に追加されます。

上のセルが空の場合、補間結果がそのまま使用されます。

ACTION の 3 つ下のセルのテキストは、例示のみを目的として提示されています。人が解読できるように列の目的を指定するために使用されます。

4 行目以降は、空でないエントリは上記の通り、補間データとして提供されます。空のセルは、このルールの Action ステートメントを省略することになります。

第第4章章 決定表決定表

43

Page 48: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

置き換えテキストにコンマが含まれている場合、$param の代わりに $1 を使用できません。

バグを報告する

4.18. METADATA ステートメント

METADATA とのヘッダーがついた列の場合、その後の行にあるセルは生成ルールに対するメタデータのアノテーションとなります。

METADATA の 1 つ下のセルにあるテキストは無視されます。

METADATA の 2 つ下にあるセルのテキストはルールの行のセルからの値を使用しますが、上記の通り補間により左右されます。メタデータマーカー文字 @ は自動的に接頭辞として追加され、このセルのテキストとして含めるべきではありません。

METADATA の 3 つ下のセルのテキストは、例示のみを目的として提示されています。人が解読できるかたちで列の目的を指定するために使用されます。

4 行目以降は、空でないエントリは上記の通り、補間データとして提供されます。空のセルは、このルールのメタデータのアノテーションを省略することになります。

バグを報告する

4.19. セルデータ補間の例

テンプレートが Foo(bar == $param) でセルが 42 の場合、結果は Foo(bar == 42) となります。

テンプレートが Foo(bar < $1, baz == $2) でセルに 42,43 が含まれる場合、結果は Foo(bar < 42, baz ==43) になります。

テンプレートが forall(&&){bar != $} でセルに 42,43 が含まれる場合、bar != 42 && bar != 43 との結果になります。

バグを報告する

4.20. セル内での作業する際のヒント

同じセル内に複数のパッケージ名がある場合、コンマで区切る必要があります。

型と変数名のペアはコンマで区切る必要があります。

関数は、DRL ファイルに表示されるとおりに記述して、"RuleSet" キーワードと同じ列に表示する必要があります。関数は、全ルールの行の上部、真ん中、または下部に設定することができます。

複数の定義を 1 つのセルにパッキングするのではなく、Import、Variables、Functions、Queries を繰り返して使用することができます。

末尾の挿入マーカーは省略可能です。

JBoss Rules 5 リファレンスガイドリファレンスガイド

44

Page 49: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バインディング変数を定義することができます。

オブジェクト型の行に何でも設定することができます。バインディング変数の定義以外は、リテラルに挿入するための追加パターンとすることも可能です。

ACTION ヘッダーの下にあるセルは空のままでも結構です。このスタイルを使用すると、メソッド呼び出し 1 つだけでなく、何でも結果に使用できます (同じ手法を CONDITION 列でも適用できます)。

バグを報告する

4.21. SPREADSHEETCOMPILER クラス

SpreadsheetCompiler クラスは、drools-decisiontables モジュールの API スプレッドシートベースの決定表で使用する主なクラスです。このクラスは、様々な形式でスプレッドシートを使用して DRLでルールを生成します。

SpreadsheetCompiler を使用して部分的なルールファイルを生成して、ファクトの後に完全なルールパッケージをアセンブルすることができます。こうすることで、必要に応じて技術的なものとそうでないものを分けることができます。

バグを報告する

4.22. スプレッドシートベースの決定表の使用

手順手順4.1 タスクタスク

1. ベースとして使用可能なサンプルのスプレッドシートを生成します。

2. Rule Workbench IDE プラグインを使用する場合、ウィザードを使用してテンプレートからスプレッドシートを生成します。

3. XSL 互換のスプレッドシートエディターを使用して XSL を変更します。

バグを報告する

4.23. LISTS

Excel では、値の lists を作成できます。これらの Lists は他のワークシートに保存して、セルに対して有効な値のリストを提供することができます。

バグを報告する

4.24. 改訂管理

ルールに変更が加えられると、より古いバージョンはアーカイブされます。JBoss Rules のアプリケーションによっては、履歴変更を保存する機能に制限があるものありますが、別の改訂管理の手段を使用するよう推奨しています。

バグを報告する

4.25. 表形式のデータソース

第第4章章 決定表決定表

45

Page 50: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

テーブル形式のデータソースは、ルールデータのソースとして使用することができ、また多数のルールを生成するためのテンプレートを作成することができます。これにより、スプレッドシートや既存のデータベースのルールなどをさらに柔軟にすることができます (テンプレートを先に開発することでルールを生成)。

バグを報告する

4.26. ルールテンプレートの機能

ルールテンプレートを使用すると、データをルールと分離することができ、ルールのどの部分がデータ駆動型なのかといった制約がなくなります。そのため、決定表の機能をすべて利用することもできますが、以下も可能になります。

データベース (やその他の形式) へデータを格納すること

データの値を元にルールを条件付きで作成すること

ルールのあらゆる部分のデータを使用すること (例:条件演算子、クラス名、プロパティ名)

同じデータに対して違ったテンプレートを実行すること

バグを報告する

4.27. ルールテンプレートの例

以下は、ルールテンプレートがどのように使用されているか示しています。

上記の例がどのようなもので構成されているか、以下に示しています。

行 1: テンプレートはすべて template header で開始されます。

行 2-4: ヘッダーの後は列のリストで、データに表示される順番に並んでいます。この場合、最初の列 location、2 番目の列 type、3 番目の列 log を呼び出しています。

1 template header2 age3 type4 log56 package org.drools.examples.templates;78 global java.util.List list;910 template "employees"1112 rule "Current employee_@{row.rowNumber}"13 when14 Name(location == @{location})15 role(type == "@{type}")16 then17 list.add("@{log}");18 end1920 end template

JBoss Rules 5 リファレンスガイドリファレンスガイド

46

Page 51: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

行 5: 空の行は列の定義の終わりを指定します。

行 6-9: 標準のルールヘッダーテキスト。これは、標準のルール DRL で生成した DRL の一番上に表示されます。パッケージステートメント、import、global、function の定義をこの部分に挿入します。

行 10: キーワード template はルールテンプレートの最初であるとのシグナルをだします。テンプレートファイルに 1 つ以上のテンプレートがある場合もありますが、各テンプレートは一意の名前を持っています。

行 11-18: ルールテンプレート

行 20: キーワード end template はテンプレートの最後を指定します。

以下のテンプレート例は、以下のルールを生成します。

バグを報告する

4.28. ルールテンプレートの実行

手順手順4.2 タスクタスク

このコードを実行してルールテンプレートを実行します。

package org.drools.examples.templates;

global java.util.List list;

rule "Current employee_1"when Person(location == Melbourne) role(type == "receptionist")then list.add("melbourne admin");end

rule "Current employee_2"when Person(location == Sydney) Cheese(type == "recruiter")then list.add("sydney HR");end

DecisionTableConfiguration dtableconfiguration = KnowledgeBuilderFactory.newDecisionTableConfiguration();dtableconfiguration.setInputType( DecisionTableInputType.XLS );

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

kbuilder.add( ResourceFactory.newClassPathResource( getSpreadsheetName(),

第第4章章 決定表決定表

47

Page 52: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

4.29. CHANGESET の展開例

以下の例は、http URL のロケーションからルールを、クラスパスから Excel の決定表をrロードするために展開されています。

バグを報告する

4.30. CHANGESET およびディレクトリの例

コンテンツを入れるためのディレクトリを指定することができます。ファイル名拡張から型を推測できないため、すべてのファイルは指定の型でなければなりません。

バグを報告する

4.31. ナレッジエージェント

ナレッジエージェントは自動ロード、リソースのキャッシュ、リロードを行い、ナレッジベースのプロパティファイルから設定します。エージェントは、使用するリソースに変更があると、ナレッジエージェントがナレッジベースを更新または再構築します。これの戦略は、ファクトリで指定した設定

getClass() ), ResourceType.DTABLE, dtableconfiguration );

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='http:org/domain/myrules.drl' type='DRL' /><resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE"><decisiontable-conf input-type="XLS" worksheet-name="Tables_2" /></resource></add></change-set>

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='file://myfolder/' type='DRL' /></add></change-set>

JBoss Rules 5 リファレンスガイドリファレンスガイド

48

Page 53: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

により決定されますが、通常は標準のポーリングを使用したプルベースとなっています。

バグを報告する

4.32. ナレッジエージェントの例

以下は、ナレッジエージェントがどのように使用されているかを示しています。

バグを報告する

4.33. KNOWLEDGEAGENT オブジェクト

KnowledgeAgent オブジェクトは、60 秒の間隔というデフォルトのポーリングを使用してすべてのリソースを継続的にスキャンします。変更日が更新されると、新しいリソースを使用してキャッシュされたナレッジベースに変更を適用します。以前の KnowledgeBase の参照はまだ存在しており、新しく構築された KnowledgeBase にアクセスするには getKnowledgeBase() を呼び出す必要があります。ディレクトリが変更セットの一部として指定された場合、ディレクトリの全コンテンツをスキャンして変更がないか確かめます。変更の適用方法は、エージェントに渡されるKnowledgeAgentConfiguration オブジェクトの中の drools.agent.newInstance プロパティにより左右されます。

バグを報告する

4.34. ポーリングサービスの開始

手順手順4.3 タスクタスク

ポーリングを行うにはポーリングサービスと通知サービスを開始する必要があります。以下のコードを使用します。

バグを報告する

4.35. KNOWLEDGEBUILDER 向けのカスタムの CLASSLOADER

手順手順4.4 タスクタスク

1. KnowledgeBuilderConfiguration を開き、カスタムのクラスローダーを指定します。

2. カスタム設定をこれらのコンパイラーに渡す必要がある場合、KnowledgeBuilderConfiguration オブジェクトをKnowledgeAgentFactory.newKnowledgeAgent() に送ります。

バグを報告する

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) );KnowledgeBase kbase = kagent.getKnowledgeBase();

ResourceFactory.getResourceChangeNotifierService().start();ResourceFactory.getResourceChangeScannerService().start();

第第4章章 決定表決定表

49

Page 54: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

4.36. KNOWLEDGEBASE CLASSLOADER の再利用

多くの場合、ルールを実行できるように、リモートリソースのコンパイルプロセスで使用するクラスローダーは、ナレッジエージェントの kbase で必要なものと同じとなっています。

この手法を使用する場合、希望の ClassLoader をエージェント kbase に設定して、KnowledgeAgentConfiguration オブジェクトの drools.agent.useKBaseClassLoaderForCompiling プロパティを使用する必要があります。

この手法では、エージェントの kbase が使用するクラスローダーを変更することで、エージェントのkbuilder classloader をランタイム時に変更することができます。これは、Changeset の漸増処理を使用しない場合も機能します。kbase が再作成されると、その設定が再利用されクラスローダーは保持されます。

バグを報告する

4.37. KNOWLEDGEAGENTCONFIGURATION の例

以下は、KnowledgeAgentConfiguration プロパティの例です。

バグを報告する

4.38. NEWINSTANCE プロパティ

newInstance プロパティは、変更セットの処理をサポートします。

ナレッジエージェントは、1) 新しい変更セットが処理されるたびにナレッジベースを再作成するか、2) キャッシュされたナレッジベースを壊すことなく変更セットに適用するかの 2 種類の方法で、変更セットを処理することができます。この動作は、Agent のコンストラクターに渡される際はKnowedgeAgentConfiguration オブジェクトの newInstance プロパティで制御されます。

バグを報告する

4.39. NEWINSTANCE プロパティの使用

newInstance が true (デフォルト値) に設定されている場合、エージェントはエージェント内のキャッシュナレッジベースを破棄し、Change set の変更を含む新しいものを作成します。newInstance がfalse に設定されている場合、Change set は直接キャッシュされたナレッジベースに適用されます。

KnowledgeBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(null, customClassLoader);KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig); //kbase with custom classloaderKnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();aconf.setProperty("drools.agent.newInstance", "false"); //incremental change set processing enabledaconf.setProperty("drools.agent.useKBaseClassLoaderForCompiling", "true");KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kbase, aconf);

JBoss Rules 5 リファレンスガイドリファレンスガイド

50

Page 55: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Change set のリソースで変更されなかったルールは、ナレッジベースで置き換えられず、変更または削除されたルールがキャッシュナレッジベースから変更または削除されます。Functions、Queries、Definition 型は、変更の有無に拘らず常にキャッシュナレッジベースで置き換えられます。

バグを報告する

4.40. NEWINSTANCE の例

以下のコードスニペットは、newInstance プロパティを false に設定して、新しいナレッジエージェントを作成します。

バグを報告する

4.41. リモートの HTTP リソースキャッシュ

ナレッジエージェントは、http(s) URL からリソースをリモートから「プル」することができます。

バグを報告する

4.42. 再起動後のリソースキャッシュのリストア

手順手順4.5 タスクタスク

リソースがリモートですでに利用できなくなっている場合 (例:リモートのサーバーが再起動された場合) に再起動に耐えるようにするには、システムプロパティ drools.resource.urlcache を設定します (アプリケーションの書き込み権限があるディレクトリに設定するようにしてください)。ナレッジエージェントは、そのディレクトリ内にリモートリソースのコピーをキャッシュします。

例えば、java コマンドライン -Ddrools.resource.urlcache=/users/someone/KnowledgeCache を使用すると、再起動されてもエージェントが使用できるように、リソースのローカルコピー (ルール、パッケージなど) をそのディレクトリに保存します (リモートのリソースが利用できるようになり、更新されると、自動的にローカルのキャッシュコピーを更新されます)。

バグを報告する

KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();aconf.setProperty("drools.agent.newInstance", "false");KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent("test agent", null, aconf);

第第4章章 決定表決定表

51

Page 56: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第5章 処理

5.1. アジェンダ

アジェンダは Rete 機能です。WorkingMemory のアクション中に、ルールが完全合致して実行できるようになる場合があります。ワーキングメモリのアクション 1 つで、複数のルールが実行できるようになる可能性があります。ルールが完全合致すると、アクティベーションが作成され、ルールと合致ファクトを参照して、アジェンダに設定します。アジェンダは、競合解消戦略を使用して、これらのアクティベーションの実行の順番を管理します。

バグを報告する

5.2. アジェンダの処理

エンジンは、以下の 2 つのフェーズのサイクルを繰り返します。

1. ワーキングメモリアクション。これは、Consequence (RHS 自体) か 主な Java アプリケーションのプロセスなど、作業が実行される場所です。Consequence が終了するか、主要なアプリケーションプロセスが fireAllRules() を呼び出すと、エンジンはアジェンダ評価フェースに切り替えられます。

2. アジェンダ評価。これは、発火するルールの選択を試みます。ルールが見つからなかった場合、そのまま存在して、見つかった場合はそのルールを発火し、このフェーズを再度ワーキングメモリアクションに切り替えます。

このプロセスは、アジェンダがなくなるまで繰り返されます。アジェンダがなくなると、呼び出し中のアプリケーションに制御が返されます。ワーキングメモリアクションが実行されている間は、ルールは発火されません。

バグを報告する

5.3. デフォルトの競合解消戦略

Salience (優先順位優先順位)

他のルールよりも特定のルールのほうが優先度が (大きい数字を割り当てます) 高いことを指定できます。この場合は、高い salience を持つルールが優先されます。

LIFO (Last In, First Out)

LIFO 優先順位は、割り当てられたワーキングメモリアクションのカウンター値をベースにしています。この際、同じアクションが同じ値を受け取ると作成されるルールをすべて使用します。同じ優先順位を持つ発火セットの実行順は任意です。

注記注記

一般的なルールとして、特定の順番で発火されるルールに依存したり、フローを気にせずルールを作成したりするのはよくありません。しかし、フローが必要な場合は、アジェンダグループ、ルールフローグループ、アクティベーショングループ、コントロール/セマフォファクト (を含むがこれに限らない) などの可能性が多数存在します。この点については後のセクションで説明します。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

52

Page 57: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

5.4. AGENDAGROUP

アジェンダグループとは、アジェンダでルールを分割する方法です。「フォーカス」があるのは、1回に 1 つのグループのみになります。つまり、そのグループ内のルールに対してのみアクティベーションが有効になります。また、「自動フォーカス」のルールを持たせることも可能です。これは、ルールの条件が true の場合にそのアジェンダグループにフォーカスが当たるようになっています。

アジェンダグループは、CLIPS の用語では「モジュール」として知られています。アジェンダグループは、分類されたルールの間のフローを作成する方法を提供します。ルールエンジンや API を使用して、フォーカスが当たっているグループを切り替えることができます。ルールに、複数のフェーズや処理の順番が必要であるとはっきり分かっている場合は、この目的でアジェンダグループの使用を検討してください。

バグを報告する

5.5. SETFOCUS()

setFocus() が呼び出されるたびに、指定のアジェンダグループをスタックにプッシュします。フォーカスグループが空の場合スタックから取り出され、一番上にあるフォーカスグループが評価されます。アジェンダグループはスタックの複数の箇所で現れます。デフォルトのアジェンダグループは"MAIN" で、アジェンダグループが指定されていないルールはすべてこのグループに入っています。また、このグループは常にスタックの最初に来て、デフォルトで最初にフォーカスがあたっています。

バグを報告する

5.6. SETFOCUS() の例

以下は、setFocus()要素がどのように使用されているかを示しています。

バグを報告する

5.7. ACTIVATIONGROUP

アクティベーショングループは、同じ "activation-group" ルール属性を持つルール同士をバインドしたセットのことです。このグループ内で 1 つのルールのみが発火でき、そのルールが発火されると、それ以外のすべてのルールはアジェンダから取り消されます。発火の順番が来る前にすべてのアクティベーションを取り消す clear() メソッドは、いつでも呼び出すことができます。

バグを報告する

5.8. ACTIVATIONGROUP の例

以下は、ActivationGroup がどのように使用されているか示しています。

バグを報告する

5.9. RULEFLOWGROUP

ルールフローグループは、"ruleflow-group" ルール属性に紐付けされたルールのグループです。これら

ksession.getAgenda().getAgendaGroup( "Group A" ).setFocus();

ksession.getAgenda().getActivationGroup( "Group B" ).clear();

第第5章章 処理処理

53

Page 58: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

のルールは、グループがアクティブな状態でないと発火できず、グループ自体は、グループを表すノードに ruleflow の図が到達してからでなければアクティブにはなりません。ここでも、アジェンダに残っているアクティベーションをすべてキャンセルするために、clear() メソッドをいつでも呼び出すことができます。

バグを報告する

5.10. RULEFLOWGROUP の例

これは、RuleFlowGroup プロパティがどのように使用されているかを示しています。

バグを報告する

5.11. ルールとメソッドの違い

メソッドは直接呼び出される。

特定のインスタンスを渡す。

1 つの呼び出しで実行されるのは 1 つである。

ルールは、エンジンに挿入される限りデータを照合していき実行される。

ルールは直接呼び出すことができない。

特定のインスタンスがルールに渡されることはない。

一致内容に応じて、ルールは 1 回または複数回発火することができ、また全く発火しないこともできる。

バグを報告する

5.12. クロスプロダクトの例

以下で、制約のない火災報知機の状態のルールについて表示しています。

SQL の用語では、select * from Room, Sprinkler を実行しているのとよく似ており、Roomテーブルのすべての行は Sprinkler テーブルのすべての行と結合され、以下のような出力となります。

ksession.getAgenda().getRuleFlowGroup( "Group C" ).clear();

rulewhen $room : Room() $sprinkler : Sprinkler()then System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );end

room:office sprinkler:officeroom:office sprinkler:kitchenroom:office sprinkler:livingroomroom:office sprinkler:bedroom

JBoss Rules 5 リファレンスガイドリファレンスガイド

54

Page 59: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

このようなクロスプロダクトは大きくなり、擬似データを含む場合もあります。変数制約を使ってクロスプロダクトに制約を加えて、このような状況を回避することができます。

結果、Room ごとに正しい Sprinkler を持つ 4 行分のデータだけが残ります。SQL (実際は HQL) では、該当のクエリは select * from Room, Sprinkler where Room == Sprinkler.room となります。

バグを報告する

5.13. アクティベーション、アジェンダ、コンフリクトの例

この例では、キャッシュフロー算出システムについて見ていきます。以下に、実装されたクラスを 3 つ示しています。

room:kitchen sprinkler:officeroom:kitchen sprinkler:kitchenroom:kitchen sprinkler:livingroomroom:kitchen sprinkler:bedroomroom:livingroom sprinkler:officeroom:livingroom sprinkler:kitchenroom:livingroom sprinkler:livingroomroom:livingroom sprinkler:bedroomroom:bedroom sprinkler:officeroom:bedroom sprinkler:kitchenroom:bedroom sprinkler:livingroomroom:bedroom sprinkler:bedroom

rulewhen $room : Room() $sprinkler : Sprinkler( room == $room )then System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );end

room:office sprinkler:officeroom:kitchen sprinkler:kitchenroom:livingroom sprinkler:livingroomroom:bedroom sprinkler:bedroom

public class CashFlow { private Date date; private double amount; private int type; long accountNo; // getter and setter methods here}

public class Account { private long accountNo; private double balance; // getter and setter methods here}

第第5章章 処理処理

55

Page 60: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2 津のルールを使用してその四半期の貸方と借方判断して勘定残高を更新することができます。以下の2 つのルールは、指定の期間アカウントのキャッシュフローに制約を加えます。ショートカット構文を使用してフィールド名が 2 回繰り返されないようにする "&&" に注目してください。

AccountPeriod が最初の四半期に設定されている場合、"increase balance for credits" のルールに制約を加えデータ 2 行に対して発火して、"decrease balance for debits" で、データ 1 行に対してアクションを行います。

データは挿入段階で称号され、fireAllRules() が呼び出されてから発火されます。その間、ルールと合致データはアジェンダに置かれ、アクティベーションとして参照されます。アジェンダは、fireAllRules() が呼び出されてすぐに発火可能でその結果を実行できるアクティベーションテーブルです。アジェンダのアクティベーションは順番に実行されます。これまでの実行の順番は任意となっている点に注目してください。

上記のアクティベーションがすべて発火されると、勘定残高は -25 になります。

AccountPeriod が第 2 四半期に更新されると、合致データの行は 1 つになるため、アジェンダのアクティベーションも 1 つだけとなります。

アクティベーションを発火すると、残高は 25 になります。

バグを報告する

5.14. 競合解消戦略

アジェンダに 1 つ以上のアクティベーションがあることをコンフリクト状態と呼び、競合解消戦略を使用して実行順位を決定します。最も簡単なのは、デフォルトの戦略が Salience を使用してルールの優先順位を決定します。

バグを報告する

public AccountPeriod { private Date start; private Date end; // getter and setter methods here}

rule "increase balance for credits"when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == CREDIT, accountNo == $accountNo, date >= ap.start &&<= ap.end, $amount : amount )then acc.balance += $amount;end

rule "decrease balance for debits" when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == DEBIT, accountNo == $accountNo, date >= ap.start &&<= ap.end, $amount : amount ) then acc.balance -= $amount; end

JBoss Rules 5 リファレンスガイドリファレンスガイド

56

Page 61: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

5.15. 競合解消戦略の例

各ルールのデフォルト値は 0 で、値が高いと優先順位も高くなります。これを例示するために、勘定残高の印刷をするためのルールを 1 つ追加します。目的は、ルールが借方、貸方すべてが全勘定に適用されてからルールを実行することです。これは、マイナスの salience をこのルールに割り当て、salienceがデフォルトの 0 となっている全ルールの後にこのルールが発火されるようにします。

バグを報告する

5.16. トリガーの例

表表5.1 トリガーの例トリガーの例

ルールビュールールビュー ビューのトリガービューのトリガー

バグを報告する

5.17. RULEFLOW-GROUP の例

ルールの ruleflow-group 属性の使用について以下に示しています。

rule "Print balance for AccountPeriod" salience -50 when ap : AccountPeriod() acc : Account() then System.out.println( acc.accountNo + " : " + acc.balance ); end

select * from Account acc, Cashflow cf, AccountPeriod ap where acc.accountNo == cf.accountNo and cf.type == CREDIT and cf.date >= ap.start and cf.date <= ap.end

select * from Account acc, Cashflow cf, AccountPeriod ap where acc.accountNo == cf.accountNo and cf.type == DEBIT and cf.date >= ap.start and cf.date <= ap.end

trigger : acc.balance += cf.amount

trigger : acc.balance -= cf.amount

rule "increase balance for credits" ruleflow-group "calculation"when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == CREDIT, accountNo == $accountNo,

第第5章章 処理処理

57

Page 62: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

5.18. 推論の例

以下の例では、IsAdult プロパティを使用して、年齢を推測します。

この推論関係は、どのルールでも利用できます。

さらに、ナレッジプロセスを切り離すことで、データリークや第三者が情報を変更する機会を減らします。

バグを報告する

5.19. 推論および TRUTHMAINTENANCE の実装

手順手順5.1 タスクタスク

1. ルールセットを開きます。この例では、バス定期券発行システムを使用します。

date >= ap.start &&<= ap.end, $amount : amount )then acc.balance += $amount;end

rule "Print balance for AccountPeriod" ruleflow-group "report"when ap : AccountPeriod() acc : Account()then System.out.println( acc.accountNo + " : " + acc.balance ); end

rule "Infer Adult"when $p : Person( age >= 18 )then insert( new IsAdult( $p ) )end

$p : Person()IsAdult( person == $p )

rule "Issue Child Bus Pass" when $p : Person( age < 16 )then insert(new ChildBusPass( $p ) );end rule "Issue Adult Bus Pass" when $p : Person( age >= 16 )

JBoss Rules 5 リファレンスガイドリファレンスガイド

58

Page 63: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. insertLogical ファクトを挿入して、推論する用語を追加します。

ファクトが論理的に挿入されました。このファクトは、When 句が true かどうかにより左右されます。つまり、ルールが false の場合、ファクトは自動的に削除されます。2 つのルールは相互排他的であるため、これは特にうまく機能します。上記のルールでは、子供が 16 歳未満であると、IsChild ファクトが挿入されます。その人が 16 歳以上になると自動的に削除され、IsAdult ファクトが挿入されます。

3. 定期券を発行するコードを挿入します。これらは、TMS ではカスケードされた取り消しに対して論理挿入の連鎖ができるため、論理的に挿入することもできます。

この人が 15 歳から 16 歳になると、IsChild ファクトが自動的に取り消されるだけでなく、ChildBussPass ファクトも取り消されます。

4. 'not' 条件要素を挿入して通知を処理します (この場合、定期券返却の依頼)。TMS が自動的にChildBussPass オブジェクトを取り消すと、このルールがトリガーして、この人に依頼が送信されます。

バグを報告する

then insert(new AdultBusPass( $p ) );end

rule "Infer Child" when $p : Person( age < 16 )then insertLogical( new IsChild( $p ) )endrule "Infer Adult" when $p : Person( age >= 16 )then insertLogical( new IsAdult( $p ) )end

rule "Issue Child Bus Pass" when $p : Person( ) IsChild( person == $p )then insertLogical(new ChildBusPass( $p ) );end rule "Issue Adult Bus Pass" when $p : Person( age >= 16 ) IsAdult( person =$p )then insertLogical(new AdultBusPass( $p ) );end

rule "Return ChildBusPass Request "when $p : Person( ) not( ChildBusPass( person == $p ) )then requestChildBusPass( $p );end

第第5章章 処理処理

59

Page 64: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第6章 ルール言語

6.1. KNOWLEDGEBUILDER

KnowledgeBuilder は、DRL ファイルや Excel ファイルなどのソースファイルを取得して、ナレッジベースが消費可能なルールやプロセス定義のナレッジパッケージに変換します。ResourceType クラスは、ビルダーが処理するように依頼されたリソース型を示します。

バグを報告する

6.2. RESOURCEFACTORY

ResourceFactory には、java.io.Reader、classpath、URL、java.io.File やバイト配列などの複数のソースからリソースをロードする機能があります。決定表 (Excel の .xls ファイル) などのバイナリファイルは、Reader で渡してはいけません。これは、テキストベースのテキストのみに適しています。

バグを報告する

6.3. 新しい KNOWLEDGEBUILDER の作成

手順手順6.1 タスクタスク

1. KnowledgeBuilderFactory を開きます。

2. 新規のデフォルト設定を作成します。

3. 以下を設定に入力します。

最初のパラメーターは任意でプロパティ用です。空白のままにすると、デフォルトオプションが使用されます。オプションのパラメーターは、方言の変更や新規の accumulator 関数の登録などに使用することができます。

4. カスタムの ClassLoader で KnowledgeBuilder を追加するには、以下のコードを使用します。

バグを報告する

6.4. DRL リソースの追加

手順手順6.2 タスクタスク

1. 型のリソースは反復的に追加することができます。以下は、DRL ファイルを追加しています。ナレッジビルダーは、複数の名前空間を処理できるため、名前空間が何であってもリソースを組み合わせることができます。

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

KnowledgeBuilderConfiguration kbuilderConf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, classLoader );KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(kbuilderConf);

JBoss Rules 5 リファレンスガイドリファレンスガイド

60

Page 65: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. リソールの追加のたびに、コンパイルの結果を確認します。KnowledgeBuilder は 3 種類の重要度 (ERROR、WARNING、INFO) とのコンパイル結果のレポートを出します。

ERROR は、リソースのコンパイルに失敗したことを指します。エラーがある場合、リソースの追加や、ナレッジパッケージの取得をこれ以上行わないようにしてください。エラーがない場合、getKnowledgePackages() は何も返しません。

WARNING および INFO の結果は無視しても構いませんが、検証用に提供されています。

バグを報告する

6.5. KNOWLEDGEBUILDER 結果の確認方法

KnowledgeBuilder API は、重要度一覧に関するビルドの結果を確認、取得するために複数のメソッドを提供しています。

KnowledgeBuilder API は、hasErrors() および getErrors() のエラーのみを確認する helper メソッドが 2 つ含まれています。

バグを報告する

6.6. KNOWLEDGEPACKAGES の取得

リソースがすべて追加され、エラーがない場合、ナレッジパッケージのコレクションを取得できます。パッケージの名前空間ごとに KnowledgePackage が 1 つあるため、java.util.Collection となっています。これらのナレッジパッケージは直列化可能で、デプロイメントの 1 ユニットとして使用されます。

以下は、KnowledgePakcage の取得の例をです。

kbuilder.add( ResourceFactory.newFileResource( "/project/myrules.drl" ), ResourceType.DRL);

/** * Return the knowledge builder results for the listed severities. * @param severities * @return */ KnowledgeBuilderResults getResults(ResultSeverity... severities); /** * Checks if the builder generated any results of the listed severities * @param severities * @return */ boolean hasResults(ResultSeverity... severities ;

if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return;}

第第6章章 ルール言語ルール言語

61

Page 66: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

6.7. KNOWLEDGEBUILDER の展開例

以下は、KnowledgeBuilder のパッケージ全体例となります。

バグを報告する

6.8. バッチモードでの KNOWLEDGEBUILDER の使用

KnowledgeBuilder には、Fluent interfance (流れるようなインターフェース) を使用するバッチモードがあります。KnowledgeBuilder は以下の例のように、1 度に複数の DRL を構築することができます。

バグを報告する

6.9. 最後に追加した DRL ビルドの破棄

KnowledgeBuilder (バッチモードの使用の有無に拘らず) を使って、最後の DRL ビルドで追加されたものを破棄することができます。これは、KnowledgeBuilder にエラーのある DRL ビルドを追加した状態からリカバリします。以下の例を確認してください。

Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return;}

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newFileResource( "/project/myrules1.drl" ), ResourceType.DRL);kbuilder.add( ResourceFactory.newFileResource( "/project/myrules2.drl" ), ResourceType.DRL);

if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return;}

Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.batch() .add( ResourceFactory.newFileResource( "/project/myrules1.drl" ), ResourceType.DRL ) .add( ResourceFactory.newFileResource( "/project/myrules2.drl" ), ResourceType.DRL ) .add( ResourceFactory.newFileResource( "/project/mytypes1.drl" ), ResourceType.DRL ) .build();

kbuilder.add( ResourceFactory.newFileResource( "/project/wrong.drl" ),

JBoss Rules 5 リファレンスガイドリファレンスガイド

62

Page 67: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

6.10. 設定および CHANGESET XML を使用した構築

ChangeSet XML 内の設定を使用して定義を作成します。単純な XML ファイルは add、remove、modify の 3 つの要素をサポートします。これらはそれぞれ、設定エンティティを定義する <resource>サブ要素の配列が含まれています。

バグを報告する

6.11. CHANGESET XML の XML スキーマ (標準ではない)

以下は、標準ではない ChangeSet のスキーマです。

ResourceType.DRL );if ( kbuilder.hasErrors() ) { kbuilder.undo();}

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://drools.org/drools-5.0/change-set" targetNamespace="http://drools.org/drools-5.0/change-set"><xs:element name="change-set" type="ChangeSet"/><xs:complexType name="ChangeSet"><xs:choice maxOccurs="unbounded"><xs:element name="add" type="Operation"/><xs:element name="remove" type="Operation"/><xs:element name="modify" type="Operation"/></xs:choice></xs:complexType><xs:complexType name="Operation"><xs:sequence><xs:element name="resource" type="Resource" maxOccurs="unbounded"/></xs:sequence></xs:complexType><xs:complexType name="Resource"><xs:sequence><!-- To be used with <resource type="DTABLE"...> --><xs:element name="decisiontable-conf" type="DecTabConf" minOccurs="0"/></xs:sequence><!-- java.net.URL, plus "classpath" protocol --> <xs:attribute name="source" type="xs:string"/><xs:attribute name="type" type="ResourceType"/></xs:complexType><xs:complexType name="DecTabConf"><xs:attribute name="input-type" type="DecTabInpType"/><xs:attribute name="worksheet-name" type="xs:string" use="optional"/></xs:complexType><!-- according to org.drools.builder.ResourceType --><xs:simpleType name="ResourceType"><xs:restriction base="xs:string"><xs:enumeration value="DRL"/><xs:enumeration value="XDRL"/><xs:enumeration value="DSL"/><xs:enumeration value="DSLR"/><xs:enumeration value="DRF"/><xs:enumeration value="DTABLE"/><xs:enumeration value="PKG"/><xs:enumeration value="BRL"/><xs:enumeration value="CHANGE_SET"/></xs:restriction></xs:simpleType><!-- according to org.drools.builder.DecisionTableInputType --><xs:simpleType name="DecTabInpType"><xs:restriction base="xs:string"><xs:enumeration value="XLS"/><xs:enumeration value="CSV"/></xs:restriction></xs:simpleType></xs:schema>

第第6章章 ルール言語ルール言語

63

Page 69: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第7章 CHANGESET

7.1. CHANGESET

changeset 機能により、API を使用しないナレッジベースの構築がスムーズに行えるようになります。Changeset には、多数のリソースを含めることができ、追加の設定情報 (現在は決定表でのみ必要ですが) もサポートすることが可能です。

changeset.xml ファイルには、これに関するリソースの一覧が含まれています。このファイルから別の changeset XML ファイルに再帰的に参照することも可能です。

バグを報告する

7.2. CHANGESET の例

プロトコルを指定するプリフィックスを使用するリソースのアプローチが採用されています。"file" や"http"、追加の "classpath" などの java.net.URL で提供されているすべてのプロトコルに対応しています。型属性はファイル名の拡張から推測できないため,現在、リソース毎に必ず型属性を指定する必要があります。これについて、以下に例で示しています。

上記の例は、リソース型を CHANGE_SET に変更して使用することができます。

バグを報告する

7.3. CHANGESET XML の例

以下は、基本的な ChangeSet XML スキーマの例です。

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='http:org/domain/myrules.drl' type='DRL' /></add></change-set>

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newClasspathResource( "myChangeSet.xml", getClass() ), ResourceType.CHANGE_SET );if ( kbuilder.hasErrors() ) { System.err.println( builder.getErrors().toString() );}

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='file:/project/myrules.drl' type='DRL' /></add></change-set>

第第7章章 CHANGESET

65

Page 70: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

7.4. CHANGESET プロトコル

ChangeSet は、"file"、"http"、追加の "Classpath" など java.net.URL が提供する全プロトコルに対応しています。型属性はファイル名の拡張から推測できないため、現在、リソース毎に必ず型属性を指定する必要があります。

file: プレフィックスを使用して、リソースのプロトコルに意味をもたせます。

注記注記

XML スキーマを使用する場合、ChangeSet XML 自体が ClassPath リソースによりロードされない限り、ナレッジビルダーが使用するクラスローダーにデフォルト設定されます。この場合、そのリソースに対して指定されたクラスローダーを使用します。

バグを報告する

7.5. CHANGESET XML のロード

手順手順7.1 タスクタスク

1. ChangeSet をロードするには API を使用します。

2. 以下のコードを使用して、ChangeSet XML にアクセスします。

バグを報告する

7.6. リソース設定を持つ CHANGESET XML の例

以下の例は、お使いの ChangeSet にどのようにリソース設定を組み込むのかを提示しています。

kbuilder.add( ResourceFactory.newUrlResource( url ), ResourceType.CHANGE_SET );

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd http://anonsvn.jboss.org/repos/labs/labs/drools/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='http:org/domain/myrules.drl' type='DRL' /><resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE"><decisiontable-conf input-type="XLS" worksheet-name="Tables_2" /></resource></add></change-set>

JBoss Rules 5 リファレンスガイドリファレンスガイド

66

Page 71: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

7.7. CHANGESET XML およびディレクトリ

以下のコードは、ディレクトリのコンテンツを ChangeSet に追加することができます。

注記注記

現在、フォルダー内のリソースはすべて同じ型である必要があります。ナレッジエージェントを使用している場合、追加、変更、削除されたリソースがないか継続的にスキャンして、キャッシュのナレッジベースを再構築します。

バグを報告する

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd http://anonsvn.jboss.org/repos/labs/labs/drools/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' ><add><resource source='file:/projects/myproject/myrules' type='DRL' /></add></change-set>

第第7章章 CHANGESET

67

Page 72: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第8章 構築

8.1. ビルド結果の重要度

ビルドテストの型が持つデフォルトの重要度を変更することができます。例えば、既存ルールで名前が重複している新しいルールをパッケージに追加する場合などに便利です (この場合、デフォルトの動作は、古いルールを新しいルールで置き換え、INFO としてレポートします)。デプロイメントによっては、ルールの更新を避け、エラーとしてレポートしたほうがいい場合もあります。

バグを報告する

8.2. デフォルトのビルド結果の重要度設定

手順手順8.1 タスクタスク

1. システムプロパティまたは設定ファイルを使用して重要度を設定するには、以下のプロパティを挿入します。

2. API を使用して重要度を変更するには、以下のコードを使用します。

バグを報告する

8.3. KNOWLEDGEPACKAGE

ナレッジパッケージは、ルールやプロセスなどナレッジ定義の集まりです。ナレッジビルダーによりナレッジパッケージは作成されます。ナレッジパッケージは、埋め込み型で直列化可能です。現在、このパッケージにより基本的なデプロイメントユニットを形成します。

注記注記

ナレッジパッケージインスタンスは、ナレッジベースに追加した後は再利用できません。別のナレッジベースにインスタンスを追加する必要がある場合、直列化して「クローン作成した」結果を使用します。

バグを報告する

// sets the severity of rule updatesdrools.kbuilder.severity.duplicateRule = <INFO|WARNING|ERROR>// sets the severity of function updatesdrools.kbuilder.severity.duplicateFunction = <INFO|WARNING|ERROR>

KnowledgeBuilderConfiguration kbconf = ...

// sets the severity of rule updates to errorkbconf.setOption( KBuilderSeverityOption.get( "drools.kbuilder.severity.duplicateRule", ResultSeverity.ERROR ) ); // sets the severity of function updates to errorkbconf.setOption( KBuilderSeverityOption.get( "drools.kbuilder.severity.duplicateFunction", ResultSeverity.ERROR ) );

JBoss Rules 5 リファレンスガイドリファレンスガイド

68

Page 73: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

8.4. 新しい KNOWLEDGEBASE の作成

手順手順8.2 タスクタスク

1. このデフォルト設定を使用して新しい KnowledgeBase を作成します。

2. カスタムのクラスローダーが KnowledgeBuilder で使用してデフォルトのクラスローダー以外で型を解決する場合、KnowledgeBase に設定する必要があります。この手法は、KnowledgeBuilder と同じで以下のようになります。

バグを報告する

8.5. インプロセス構築およびデプロイ

プロセス内の構築は最も単純なデプロイメントの形式です。ナレッジ定義をコンパイルして、同じJVM 内のナレッジベースにこれらの定義を追加します。このアプローチでは、クラスパスに置くには drools-core.jar および drools-compiler.jar が必要です。

バグを報告する

8.6. KNOWLEDGEBASE への KNOWLEDGEPACKAGES の追加

手順手順8.3 タスクタスク

KnowledgePackages を KnowledgeBase に追加するには、以下のコードを使用します。

addKnowledgePackages(kpkgs) メソッドは、繰り返し呼び出してさらにナレッジを追加することができます。

バグを報告する

8.7. 別のプロセスでの構築およびデプロイメント

KnowledgeBase および KnowledgePackage はどちらもデプロイメントユニットで直列化可能です。つまり、必要な構築を 1 台のマシンで行い (drools-compiler.jar が必要)、他のマシンですべてをデプロイ、実行します (drools-core.jar のみが必要)。

バグを報告する

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

KnowledgeBaseConfiguration kbaseConf = KnowledgeBaseFactory.createKnowledgeBaseConfiguration( null, cl );KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );

Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kpkgs );

第第8章章 構築構築

69

Page 74: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述

これは OutputStream へ KnowledgePackage を記述するコードです。

バグを報告する

8.9. INPUTSTREAM から KNOWLEDGEPACKAGE の読み取り

以下のコードを使用して、InputStream から KnowledgePackage を読み取ります。

バグを報告する

8.10. JBOSS RULES 管理システム

JBoss Rules 管理システムは KnowledgeBases のリポジトリで、多数のルールセットを保持します。

また、システムは直列化されたナレッジパッケージをコンパイルして URL に公開し、これを使用してパッケージをロードします。

バグを報告する

8.11. STATEFULKNOWLEDGESESSIONS および KNOWLEDGEBASE の変更

KnowledgeBase は StatefulKnowledgeSession オブジェクトを作成して返し、オプションでこれらのオブジェクトへ参照することも可能です。

KnowledgeBase が変更されると、セッション内のデータに適用されます。この参照は弱参照で、これもオプションです。Boolean フラグにより制御されます。

バグを報告する

8.12. 新たな KNOWLEDGEAGENT

以下は、新規 KnowlegeAgent を作成するコードです。

ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( fileName ) );out.writeObject( kpkgs );out.close();

ObjectInputStream in = new ObjectInputStream( new FileInputStream( fileName ) );// The input stream might contain an individual// package or a collection.@SuppressWarnings( "unchecked" )Collection<KnowledgePackage> kpkgs = ()in.readObject( Collection<KnowledgePackage> );in.close();

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kpkgs );

JBoss Rules 5 リファレンスガイドリファレンスガイド

70

Page 75: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

8.13. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述

以下は、OutputStream へ KnowledgePackage を記述する方法です。

注記注記

リソースのスキャンはデフォルトでは有効ではないため、開始する必要があります。これは通知にも該当します。ResourceFactory 経由で両方とも有効にすることができます。

バグを報告する

8.14. スキャンと通知サービスの開始

以下はスキャンと通知サービスを開始するためのコードです。

バグを報告する

8.15. RESOURCECHANGESCANNER

ResourceChangeScanner は、サービスをスキャンにするために使用します。デフォルトのリソーススキャンの期間は、ResourceChangeScannerService 経由で変更することができます。適切に更新された ResourceChangeScannerConfiguration オブジェクトは、サービスの configure() メソッドに渡され、サービスがオンデマンドで再構成できるようにします。

バグを報告する

8.16. スキャン間隔の変更

以下は、スキャンの間隔を変更する際に使用するコードです。

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );kagent.applyChangeSet( ResourceFactory.newUrlResource( url ) );KnowledgeBase kbase = kagent.getKnowledgeBase();

ResourceFactory.getResourceChangeNotifierService().start();ResourceFactory.getResourceChangeScannerService().start();

ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();// Set the disk scanning interval to 30s, default is 60s.sconf.setProperty( "drools.resource.scanner.interval", "30" ); ResourceFactory.getResourceChangeScannerService().configure( sconf );

第第8章章 構築構築

71

Page 76: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

8.17. ナレッジエージェントとナレッジベース間の対話

ナレッジエージェントは、空のナレッジベースや生成したナレッジベースを処理することができます。生成したナレッジベースが指定された場合、ナレッジエージェントはナレッジベースからイテレーターを実行して、見つかったリソースにサブスクライブします。ナレッジビルダーがディレクトリ内で見つかったリソースをすべて構築できるだけでなく、その情報はナレッジビルダーにより消され、これらのディレクトリが継続してスキャンされないようにします。applyChangeSet(Resource) メソッドの一部として指定されたディレクトリのみ、モニタリングされます。

スタートポイントとして KnowledgeBase を指定する利点は、KnowledgeBaseConfiguration でそれを提供できる点です。リソースの変更が検出され新しい KnowledgeBase オブジェクトがインスタンス化されると、以前の KnowledgeBase の KnowledgeBaseConfiguration を使用します。

バグを報告する

8.18. 既存の KNOWLEDGEBASE の使用

以下は、既存の KnowledgeBase を活用するコードです。

上記の例では getKnowledgeBase() はリソースの変更が検出され新しいナレッジベースが構築されるまで指定の同じ kbase インスタンスを返します。新しいナレッジベースが構築される際は、以前の KnowledgeBase に提供された KnowledgeBaseConfiguration を使って行われます。

バグを報告する

8.19. APPLYCHANGESET() メソッド

ChangeSet XML と applyChangeSet() メソッドとを合わせて使用すると、スキャンプロセスにディレクトリを追加します。ディレクトリのスキャンで追加のファイルが検出されると、そのファイルはナレッジベースに追加されます。削除されたファイルも、変更されたファイルも、ナレッジベースから削除されます。

バグを報告する

8.20. ディレクトリのコンテンツを追加するための CHANGESET XML

この XML を使用して、ディレクトリのコンテンツを ChangeSet に追加します。

KnowledgeBaseConfiguration kbaseConf = KnowledgeBaseFactory.createKnowledgeBaseConfiguration( null, cl );KnowledgeBase kbase KnowledgeBaseFactory.newKnowledgeBase( kbaseConf );// Populate kbase with resources here.

KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent", kbase );KnowledgeBase kbase = kagent.getKnowledgeBase();

<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' ><add><resource source='file:/projects/myproject/myrules'

JBoss Rules 5 リファレンスガイドリファレンスガイド

72

Page 77: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

リソース型 PKG は、drools-compiler の依存関係が必要ではない点に注意してください。ナレッジエージェントは drools-core だけでこれらを処理することができます。

バグを報告する

8.21. KNOWLEDGEAGENTCONFIGURATION プロパティ

KnowledgeAgentConfiguration は、ナレッジエージェントのデフォルトの動作を変更するために使用します。これを使用して、ディレクトリからリソースをロードし、そのディレクトリへの変更を加え継続的なスキャンを阻止します。

バグを報告する

8.22. スキャン動作の変更

以下のコードを使用してスキャンの動作を変更します。

バグを報告する

type='PKG' /></add></change-set>

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

KnowledgeAgentConfiguration kaconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguation();// Do not scan directories, just files.kaconf.setProperty( "drools.agent.scanDirectories", "false" );KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kaconf );

第第8章章 構築構築

73

Page 78: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第9章 セッション

9.1. JBOSS RULES のセッション

セッションは、データを挿入することができプロセスインスタンスを開始できる KnowledgeBase から作成されます。KnowledgeBase の作成はリソースを集中的に使用する場合がありますが、セッションの作成はそうではありません。このような理由から、できる限り KnowledgeBases をキャッシュして、繰り返してセッションを作成できるようにするよう推奨されています。

バグを報告する

9.2. KNOWLEDGEBASE からの STATEFULKNOWLEDGESESSION の作成

以下は、KnowledgeBase から新しい StateefulKnowledgeSession を作成するコードです。

バグを報告する

9.3. WORKINGMEMORYENTRYPOINT メソッド

WorkingMemoryEntryPoint は、ファクトの挿入、更新、取得関連のメソッドを提供します。「エントリポイント」という用語は、ワーキングメモリ内にある複数のパーティションのどの部分に挿入するか選択できるということに関連しています。ほとんどのルールベースのアプリケーションは、デフォルトのエントリポイントだけで機能します。

バグを報告する

9.4. KNOWLEDGERUNTIME インターフェース

KnowledgeRuntime インターフェースは、主にエンジンとの対話を行い、ルールの結論部やプロセスアクションで利用できます。KnowledgeRuntime は、WorkingMemory および ProcessRuntime 両方からのメソッドを継承して、統合された API を提供してプロセスとルールと連携します。ルールと連携すると、KnowledgeRuntime は WorkingMemoryEntryPoint、WorkingMemory、KnowledgeRuntime 自体の 3 つのインターフェースで形成されます。

バグを報告する

9.5. ファクトの挿入

挿入とは、ファクトに関して WorkingMemory に通知する行為のことです。例えば、ksession.insert(yourObject) を使用して挿入を行うことができます。ファクトを挿入して、ルールに合致がないか検証します。つまり、ルールの発火を行うかどうかを決定する作業のすべすべててが挿入時に行われます。しかし、ファクトの挿入が完了した後に呼び出す fireAllRules() を呼び出すまで、ルールは実行されません。

バグを報告する

9.6. FACTHANDLE トークン

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

JBoss Rules 5 リファレンスガイドリファレンスガイド

74

Page 79: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

オブジェクトが挿入されると、FactHandle が返されます。この FactHandle は、WorkingMemory内に挿入されたオブジェクトを表すために使用するトークンです。このトークンは、オブジェクトの削除や変更の際に WorkingMemory と対話をする際にも使用されます。

バグを報告する

9.7. FACTHANDLE の例

バグを報告する

9.8. アイデンティティと等価

これらは、ワーキングメモリにより使用される 2 つのアサーションノードです。

アイデンティティアイデンティティ

アイデンティティとは、ワーキングメモリが IdentityHashMap を使用してアサートされたオブジェクトをすべて保存するという意味です。新しいインスタンスアサーションは常に、新しい FactHandle を返すことになりますが、インスタンスが再度アサートされると、元のファクトハンドルを返します (つまり、同じオブジェクトに対する挿入の繰り返しを無視するということです)。

等価等価

等価とは、ワーキングメモリが HashMap を使用してアサートしたオブジェクトすべてを保存するという意味です。挿入されたオブジェクトが (equal メソッドによると) 既存のファクトと等価でない場合、オブジェクトインスタンスのアサーションは、新しい FactHandle のみを返します。

注記注記

新しいインスタンスアサーションは常に、新しい FactHandle を返すことになりますが、インスタンスが再度アサートされると、元のファクトハンドルを返します (つまり、同じオブジェクトに対する挿入の繰り返しを無視するということです)。

バグを報告する

9.9. 取り消し

取り消しとは、ワーキングメモリからファクトを取り除くことです。つまり、これ以上ファクトのトラッキングと照合は行われず、アクティブ化されそのファクトに依存するルールはすべてキャンセルされるということです。ファクトがないことに依存するルールもありえます。ファクトを取り消すとルールがアクティブ化されるきっかけとなる場合があります。挿入コールにより返された FactHandle を使用して、取り消しを行うことができます。ルールの右側では、retract ステートメントを使用して、シンプルなオブジェクト参照と連携します。

バグを報告する

9.10. 取り消しの例

Job accountant = new Job("accountant");FactHandle accountantHandle = ksession.insert( accountant );

Job accountant = new Job("accountant");

第第9章章 セッションセッション

75

Page 80: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

9.11. UPDATE() メソッド

ルールエンジンは、再処理ができるようにファクトが変更されたことを通知する必要があります。update() メソッドを使用して、WorkingMemory 自体の通知ができないオブジェクトのために、オブジェクトが変更されたことを WorkingMemory に通知することができます。update() メソッドは常に、変更されたオブジェクトを 2 番目のパラメーターとして取り、イミュータブルオブジェクトに新しいインスタンスを指定することができるようになります。

注記注記

ルールの右側部分には、単一のステートメントでエンジンの変更と通知を行うため、modify ステートメントが推奨されます。あるいは、setter メソッドを呼び出してファクトオブジェクトのフィールド値を変更した後、すぐに update を呼び出す必要があります。すぐ呼び出しがされないと、他のファクトを変更する前でも、ルールエンジン内のインデックスに問題が発生する可能性があります。modify ステートメントはこの問題を回避することができます。

バグを報告する

9.12. UPDATE() の例

バグを報告する

9.13. クエリ

クエリは、ルールで使用されているようにパターンをベースとしてファクトセットを取得するために使用します。パターンがオプションのパラメーターを活用する場合もあります。クエリはナレッジベースで定義でき、ナレッジベースから合致した結果を戻すためにクエリを呼び出します。結果のコレクションが繰り返し行われている間、get メソッドを引数としてバイドした変数の名前で呼び出すことで、クエリでバインドされた識別子を使用して該当のファクトまたはファクトフィールドにアクセスすることができます。このバインドがファクトオブジェクトを参照している場合、パラメーターとして変数の名前を再度使用して getFactHandle を呼び出すことで FactHandle を取得できます。

バグを報告する

9.14. クエリの例

FactHandle accountantHandle = ksession.insert( accountant );....ksession.retract( accountantHandle );

Job accountant = new Job("accountant");FactHandle accountantHandle = workingMemory.insert( accountant );...accountant.setSalary( 45000 );workingMemory.update( accountantHandle, accountant );

QueryResults results = ksession.getQueryResults( "my query", new Object[] { "string" } );for ( QueryResultsRow row : results ) {

JBoss Rules 5 リファレンスガイドリファレンスガイド

76

Page 81: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

9.15. ライブクエリ

クエリを呼び出して、返されたセットを反復して結果を処理するのは、変更のモニタリングに適した方法ではありません。

これを軽減するために JBoss Rules は反復可能な結果セットを返すのではなくリスナーが接続されたライブクエリを提供しています。これらのライブクエリは、ビューを作成してこのビューのコンテンツ向けに変更イベントを公開することでオープンの状態を保ちます。アクティブ化するには、パラメーターでクエリを開始して結果ビューの変更をリッスンします。dispose メソッドはクエリを終了して、この反応型のシナリオを中断します。

バグを報告する

9.16. VIEWCHANGEDEVENTLISTENER の実装例

注記注記

ライブクエリの Glazed Lists 統合の例については、http://blog.athico.com/2010/07/glazed-lists-examples-for-drools-live.html を確認してください。

System.out.println( row.get( "varName" ) );}

final List updated = new ArrayList();final List removed = new ArrayList();final List added = new ArrayList(); ViewChangedEventListener listener = new ViewChangedEventListener() { public void rowUpdated(Row row) { updated.add( row.get( "$price" ) ); } public void rowRemoved(Row row) { removed.add( row.get( "$price" ) ); } public void rowAdded(Row row) { added.add( row.get( "$price" ) ); }}; // Open the LiveQueryLiveQuery query = ksession.openLiveQuery( "cars", new Object[] { "sedan", "hatchback" }, listener );......query.dispose() // calling dispose to terminate the live query

第第9章章 セッションセッション

77

Page 83: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第10章 オブジェクトとインターフェース

10.1. グローバル (GLOBAL)

グローバル (Global) はルールエンジンに公開する名前付きのオブジェクトですが、ファクトと違ってglobal をバックアップするオブジェクトに変更があってもルールの再評価はトリガーされません。Global はルールの RHS で使用されるサービスを提供するオブジェクトとして、ルールエンジンからオブジェクトを返す手段として、静的な情報を提供する際に便利です。

バグを報告する

10.2. GLOBAL との連携

手順手順10.1 タスクタスク

1. Global をワーキングメモリに実装開始するには、ルールファイルに global を宣言して、Javaオブジェクトでバックアップします。

2. ナレッジベースは global の識別子とその型を認識するようになったため、Global の名前とオブジェクトで ksession.setGlobal() を呼び出して、global とオブジェクトを関連付けることができます。

重要重要

Global の型と識別子を DRL コードで宣言しなかった場合は、この呼び出しから例外が送出されます。

3. ルールの評価をする前に Global を設定するようにしてください。そうでないと、NullPointerException が送出されてしまいます。

バグを報告する

10.3. GLOBAL の解決

Global は 3 つの方法で解決することができます。

getGlobals()

Stateless Knowledge Session メソッド getGlobals() は、セッションの global へアクセスできるようにする Global インスタンスを返します。これらは、実行呼び出しすべてに共有されます。別のスレッドで同時に実行呼び出しが実行される場合がありますので、ミュータブル global には注意してください。

Delegates

Global の解決を行う別の方法には、delegate の使用が挙げられます。global (setGlobal(String, Object) で) に値を割り当てると、識別子を値にマッピングする内部コレクション内に値が格納さ

global java.util.List list

List list = new ArrayList();ksession.setGlobal("list", list);

第第10章章 オブジェクトとインターフェースオブジェクトとインターフェース

79

Page 84: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

れます。この内部コレクションの識別子は、提供した delegate よりも優先されます。識別子がこの内部コレクションで見つからない場合、delegate global が使用されます (あれば)。

Execution

Execution scoped global は Command を使用して global を設定し、CommandExecutor に渡されます。

バグを報告する

10.4. SESSION SCOPED GLOBAL の例

以下は、Session Scoped Global の例です。

バグを報告する

10.5. STATEFULRULESESSIONS

StatefulRuleSession プロパティは、StatefulKnowledgeSession が継承して、エンジン外部から該当するルール関連のメソッドを提供します。

バグを報告する

10.6. AGENDAFILTER オブジェクト

AgendaFilter オブジェクトは、フィルターインターフェースのオプション実装です。これを使用してアクティベーションの発火の許可または拒否を行うことが可能になります。フィルタリング対象は、実装により左右されます。

バグを報告する

10.7. AGENDAFILTER の使用

手順手順10.2 タスクタスク

フィルターを使用するには、fireAllRules() を呼び出す際に指定します。以下の例では、文字列 "Test" で終わるルールのみが許可され、それ以外はフィルタリングされ除外されてしまいます。

バグを報告する

10.8. ルールエンジンのフェーズ

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();// Set a global hbnSession, that can be used for DB interactions in the rules.ksession.setGlobal( "hbnSession", hibernateSession );// Execute while being able to resolve the "hbnSession" identifier. ksession.execute( collection );

ksession.fireAllRules( new RuleNameEndsWithAgendaFilter( "Test" ) );

JBoss Rules 5 リファレンスガイドリファレンスガイド

80

Page 85: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

エンジンは、以下の 2 つのフェーズのサイクルを繰り返します。

ワーキングメモリのアクションワーキングメモリのアクション

これは、Consequence (RHS 自体) か 主な Java アプリケーションのプロセスなど、作業が実行される場所です。Consequence が終了するか、主要なアプリケーションプロセスが fireAllRules()を呼び出すと、エンジンはアジェンダ評価フェースに切り替えられます。

アジェンダ評価アジェンダ評価

これは、発火するルールの選択を試みます。ルールが見つからなかった場合、そのまま存在して、見つかった場合はそのルールを発火し、このフェーズを再度ワーキングメモリアクションに切り替えます。

このプロセスは、アジェンダがなくなるまで繰り返されます。アジェンダがなくなると、呼び出し中のアプリケーションに制御が返されます。ワーキングメモリアクションが実行されている間は、ルールは発火されません。

バグを報告する

10.9. イベントモデル

イベントパッケージは、ルールの発火、アサートされたオブジェクトなど、ルールエンジンイベントを通知する手段を提供します。これにより、例えばロギングや監査のアクティビティと、アプリケーションの主要部 (およびルール) を分割することができます。

バグを報告する

10.10. KNOWLEGERUNTIMEEVENTMANAGER

KnowlegeRuntimeEventManager インターフェースは、KnowledgeRuntime で実装され、WorkingMemoryEventManager と ProcessEventManager の 2 つのインターフェースを提供します。

バグを報告する

10.11. WORKINGMEMORYEVENTMANAGER

WorkingMemoryEventManager により、リスナーの追加や削除が可能になり、ワーキングメモリのイベントやアジェンダをリッスンすることができます。

バグを報告する

10.12. AGENDAEVENTLISTENER の追加

以下のコードスニペットは、どのようにシンプルなアジェンダーリスナーが宣言されセッションに接続されるかを示しています。発火後にアクティベーションを出力します。

ksession.addEventListener( new DefaultAgendaEventListener() { public void afterActivationFired(AfterActivationFiredEvent event) { super.afterActivationFired( event ); System.out.println( event ); }});

第第10章章 オブジェクトとインターフェースオブジェクトとインターフェース

81

Page 86: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

10.13. ワーキングメモリのイベントの出力

以下のコードにより、リスナーを追加することですべてのワーキングメモリのイベントを出力することができます。

バグを報告する

10.14. KNOWLEGERUNTIMEEVENTS

出されたイベントはすべて、KnowlegeRuntimeEvent インターフェースを実装し、このインターフェースを使用してイベントが出された実際の KnowlegeRuntime を取得することができます。

バグを報告する

10.15. KNOWLEDGERUNTIMEEVENT インターフェースに対応のイベント

現在サポートされているイベント:

ActivationCreatedEvent

ActivationCancelledEvent

BeforeActivationFiredEvent

AfterActivationFiredEvent

AgendaGroupPushedEvent

AgendaGroupPoppedEvent

ObjectInsertEvent

ObjectRetractedEvent

ObjectUpdatedEvent

ProcessCompletedEvent

ProcessNodeLeftEvent

ProcessNodeTriggeredEvent

ProcessStartEvent

バグを報告する

10.16. KNOWLEDGERUNTIMELOGGER

ksession.addEventListener( new DebugWorkingMemoryEventListener() );

JBoss Rules 5 リファレンスガイドリファレンスガイド

82

Page 87: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

KnowledgeRuntimeLogger は、JBoss Rules の統合イベントシステムで監査ログを作成します。後にEclipse 監査ビューワーなどのツールで検証できるように、この監査ログを使用してアプリケーションの実行ログを取ることができます。

バグを報告する

10.17. FILELOGGER の有効化

FileLogger を有効にしてファイルをトラッキングするには、以下のコードを使用します。

バグを報告する

10.18. JBOSS RULES での STATELESSKNOWLEDGESESSION の使用

StatelessKnowledgeSession は拡張する代わりに StatefulKnowledgeSession をラップします。これは、主に決定サービスタイプのシナリオに焦点を当てており、dispose() を呼び出す必要がなくなります。ステートレスセッションは、反復挿入や Java コードからの fireAllRules() メソッド呼び出しはサポートしていません。execute() を呼び出す行為はワンショットメソッドで、StatefulKnowledgeSession を内部でインスタンス化し、すべてのユーザーデータを追加してユーザコマンドを実行し、fireAllRules() を呼び出した後、dispose() を呼び出します。このクラスと連携するための主な方法は、CommandExecutor でサポートされているように BatchExecution(Command のサブインターフェース) を使用することですが、単純なオブジェクトの挿入だけが必要な場合のために、便利な 2 つのメソッドが提供されています。CommandExecutor および BatchExecution は、それぞれのセクションで詳しく説明します。

バグを報告する

10.19. コレクションを使用した STATELESSKNOWLEDGESESSION の実行

以下のコードは、コレクションを使った StatelessKnowledgeSession の実行例です。

バグを報告する

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "logdir/mylogfile");...logger.close();

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newFileSystemResource( fileName ), ResourceType.DRL );if (kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() );} else { KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); ksession.execute( collection );}

第第10章章 オブジェクトとインターフェースオブジェクトとインターフェース

83

Page 88: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

10.20. INSERTELEMENTS コマンドを使用したSTATELESSKNOWLEDGESESSION の実行

以下は、InsertElements コマンドを使用して StatelessKnowledgeSession を実行したコードです。

注記注記

コレクションと個別の要素を挿入するには、CommandFactory.newInsert(collection) を使用します。

バグを報告する

10.21. BATCHEXECUTIONHELPER

CommandFactory のメソッドは、対応のコマンドを作成して、XStream とBatchExecutionHelperを使用してすべてをマーシャリングすることができます。BatchExecutionHelper は、XML 形式の詳細および BatchExecution および ExecutionResults のマーシャリングを自動化する JBossRules Pipuline の使用方法を提供します。

バグを報告する

10.22. COMMANDEXECUTOR インターフェース

CommandExecutor インターフェースは、"out" パラメーターを使用してデータのエクスポートができるようにします。つまり、挿入したファクト、Global、クエリの結果はすべてこのインターフェースを使用して返されることになります。

バグを報告する

10.23. OUT 識別子

以下は、Out 識別子の例です。

ksession.execute( CommandFactory.newInsertElements( collection ) );

// Set up a list of commandsList cmds = new ArrayList();cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) );cmds.add( CommandFactory.newInsert( new Person( "jon", 102 ), "person" ) );cmds.add( CommandFactory.newQuery( "Get People" "getPeople" );

// Execute the listExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) );

// Retrieve the ArrayListresults.getValue( "list1" );// Retrieve the inserted Person factresults.getValue( "person" );// Retrieve the query as a QueryResults instance.results.getValue( "Get People" );

JBoss Rules 5 リファレンスガイドリファレンスガイド

84

Page 90: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第11章 モードとメソッド

11.1. シーケンシャルモード

JBoss Rules のシーケンシャルモードを使用すると、より簡単な方法でエンジンを使用することができます。ユーザーがステートレスセッションで作用してデータが初期のデータセットからアサートまたは変更されない場合、再評価の必要性なしにルールを使用できます。

バグを報告する

11.2. シーケンシャルモードのオプション

シーケンシャルモードを使用時に選べるオプションがいくつかあります。

1. ルールセット内の salience (優先順位) および位置でルールの順番を決める (ルールの終端ノードで sequence 属性を設定)。

2. 配列の作成 (ルールアクティベーション候補ごとに 1 要素)。要素の位置は発火順位を示す。

3. right-input オブジェクトメモリ以外のノードのメモリをすべて無効にする。

4. Left Input Adapter ノードの伝播を切断して、オブジェクトとノードがコマンドオブジェクトで参照されるようにする。これは後に実行できるようにワーキングメモリのリストに追加される。

5. すべてオブジェクトをアサート。すべてのアサートが終了して、right-input ノードのメモリが生成されると、コマンドリストを確認して順番に実行してく。

6. 結果となるすべてのアクティベーションは、決定されたルールの順番をベースに配列内に設定される必要がある。最初と最後に生成された要素を記録して反復の幅を減らす。

7. アクティベーションの配列を繰り返して、生成した要素を順番に実行する。

8. ルール実行の最大回数がある場合、ネットワーク評価を早く終了して配列内でルールをすべて発火する。

バグを報告する

11.3. シーケンシャルモードの有効化

手順手順11.1 タスクタスク

1. ステートレスセッションを開始します。

2. シーケンシャルモードはデフォルトで無効になっています。有効にするには、RuleBaseConfiguration.setSequential(true) を呼び出すか、rulebase 設定プロパティ drools.sequential を true に設定します。

3. シーケンシャルモードが動的アジェンダに分類できるように、 SequentialAgenda.DYNAMIC で setSequentialAgenda を呼び出します。

4. オプションで、JBossRules.sequential.agenda プロパティを sequential または dynamic に設定します。

JBoss Rules 5 リファレンスガイドリファレンスガイド

86

Page 91: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

11.4. COMMANDFACTORY

CommandFactory オブジェクトは、コマンドがステートレスセッションで実行できるようにします。完了すると、セッションを破棄する前にファクトリが fireAllRules() を実行します。

バグを報告する

11.5. 対応の COMMANDFACTORY オプション

これらのオプションはすべて CommandFactory と互換性があります。

FireAllRules

GetGlobal

SetGlobal

InsertObject

InsertElements

Query

StartProcess

BatchExecution

バグを報告する

11.6. 挿入コマンド

InsertObject は、オプションの "out" 識別子で単一のオブジェクトを挿入します。InsertElements は Iterable を反復して各要素を挿入します。こうすることで、ステートレスナレッジセッションがクエリをあらゆる順序で処理、実行することができます。

バグを報告する

11.7. 挿入コマンドの例

バグを報告する

11.8. 実行メソッド

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();ExecutionResults bresults = ksession.execute( CommandFactory.newInsert( new Car( "sedan" ), "sedan_id" ) );Sedan sedan = bresults.getValue( "sedan_id" );

第第11章章 モードとメソッドモードとメソッド

87

Page 92: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

実行メソッドを使用して、1 度に 1 つのコマンドを実行します。常にこのメソッドは ExecutionResults インスタンスを返して、stilton_id などの out 識別子を指定している場合、コマンドの結果にアクセスできるようになります。

バグを報告する

11.9. 実行メソッドの例

バグを報告する

11.10. BATCHEXECUTION コマンド

BatchExecution コマンドにより、複数のコマンドを 1 度に実行することができます。これは、コマンドリストから作成された複合コマンドのことを指します。Execute はリストの項目を繰り返して順番にコマンドを実行します。つまり、 execute(...) 呼び出し 1 つで、オブジェクトを挿入、プロセスを開始、fireAllRules を呼び出し、クエリを実行することができます。

バグを報告する

11.11. FIREALLRULES コマンド

FireAllRules コマンドは、最後にルールを自動的に実行します。手動でオバーライドする関数型です。

バグを報告する

11.12. OUT 識別子

コマンドは Out 識別子に対応しています。Out 識別子が設定されているコマンドは、結果を返されたExecutionResults インスタンスに追加します。

バグを報告する

11.13. OUT 識別子の例

以下の例は、BatchExecution コマンドを使用して Out 識別子がどのように機能するか示しています。

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();Command cmd = CommandFactory.newInsertElements( Arrays.asList( Object[] { new Car( "sedan" ), new Car( "hatchback" ), new Car( "convertible" ), });ExecutionResults bresults = ksession.execute( cmd );

StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

List cmds = new ArrayList(); cmds.add( CommandFactory.newInsertObject( new Car( "red", 1), "red") );cmds.add( CommandFactory.newStartProcess( "process cars" ) );cmds.add( CommandFactory.newQuery( "cars" ) );ExecutionResults bresults = ksession.execute(

JBoss Rules 5 リファレンスガイドリファレンスガイド

88

Page 93: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

上記の例では、複数のコマンドが実行されます。これらの内 2 つは ExecutionResults を生成します。クエリコマンドはデフォルトで同じ識別子をクエリ名として使用しますが、別の識別子にマッピングすることもできます。

バグを報告する

11.14. 実行 XML の例

カスタムの XStream マーシャラーは、JBoss Rules Pipelin と併用して XML スクリプトが実現できサービスに適しています。これに関して 2 つの例を以下に示しています。

BatchExecution XML:

ExecutionResults XML:

バグを報告する

11.15. 実行マーシャリングの例

以下は XML にマーシャリングされた BatchExecution の例です。

CommandFactory.newBatchExecution( cmds ) );Car red = ( Car ) bresults.getValue( "red" );QueryResults qresults = ( QueryResults ) bresults.getValue( "cars" );

<batch-execution><insert out-identifier='outRed'><org.drools.Car><type>red</type><price>25000</price><oldPrice>0</oldPrice></org.drools.Car></insert></batch-execution>

<execution-results><result identifier='outBlue'><org.drools.Car><type>Blue</type><oldPrice>25</oldPrice><price>30000</price></org.drools.Car></result></execution-results>

<batch-execution><insert out-identifier="sedan"><org.drools.Car><type>sedan</type><price>1</price><oldPrice>0</oldPrice></org.drools.Car></insert><query out-identifier='cars2' name='carsWithParams'><string>hatchback</string><string>sedan</string></query></batch-execution>

第第11章章 モードとメソッドモードとメソッド

89

Page 94: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

CommandExecutor は ExecutionResults を返して、パイプラインコードスニペットで処理されます。上記の <batch-execution> XML サンプルと似た出力は以下のようになります。

バグを報告する

11.16. BATCH-EXECUTION とコマンドの例

<execution-results><result identifier="sedan"><org.drools.Car><type>sedan</type><price>2</price></org.drools.Car></result><result identifier='cars2'><query-results><identifiers><identifier>car</identifier></identifiers><row><org.drools.Car><type>hatchback</type><price>2</price><oldPrice>0</oldPrice></org.drools.Car></row><row><org.drools.Car><type>hatchback</type><price>1</price><oldPrice>0</oldPrice></org.drools.Car></row></query-results></result></execution-results>

JBoss Rules 5 リファレンスガイドリファレンスガイド

90

Page 95: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

1. 現在、スキーマ検証をサポートする XML スキーマはありません。以下が基本的なフォーマットとなっています。Root 要素は、<batch-execution> で、0 またはそれ以上のコマンド要素を含めることができます。

2. 挿入要素には、"out-identifier" 属性が含まれているため、挿入されたオブジェクトは結果ペイロードの一部として返されます。

3. <insert-elements> 要素を使用してオブジェクトのコレクションを挿入することも可能です。このコマンドは、out-identifier には対応していません。org.domain.UserClass はXStream が直列化するユーザーオブジェクトの事例として使用しています。

4. <set-global> 要素は、セッションに Global を設定します。

5. <set-global> は、他に out と out-identifier の 2 つのオプション属性にも対応しています。ブール型 out の true 値は、identifier 属性かの名前を使用して Global を <batch-execution-results> ペイロードに追加します。 out-identifier は out のように機能しますが、<batch-execution-results> ペイロードで使用した識別子をオーバーライドできます。

<batch-execution>...</batch-execution>

<batch-execution><insert out-identifier='userVar'> ... </insert></batch-execution>

<batch-execution><insert-elements><org.domain.UserClass> ... </org.domain.UserClass><org.domain.UserClass> ... </org.domain.UserClass><org.domain.UserClass> ... </org.domain.UserClass></insert-elements></batch-execution>

<batch-execution><set-global identifier='userVar'><org.domain.UserClass> ... </org.domain.UserClass></set-global></batch-execution>

<batch-execution><set-global identifier='userVar1' out='true'>

第第11章章 モードとメソッドモードとメソッド

91

Page 96: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

6. コンテンツのない <get-global> 要素があり、out-identifier 属性のみが含まれています。値の取得が <get-global> 要素の唯一の目的であるため、out 属性は必要ありません。

7. query コマンドは、パラメータークエリもパラメーターなしのクエリにも対応しています。name 属性は呼び出すクエリ名で、out-identifier は <execution-results> ペイロードのクエリ結果で使用される識別子です。

8. <start-process> コマンドは、オプションのパラメーターも受け入れます。

<org.domain.UserClass> ... </org.domain.UserClass></set-global><set-global identifier='userVar2' out-identifier='alternativeUserVar2'><org.domain.UserClass> ... </org.domain.UserClass></set-global></batch-execution>

<batch-execution><get-global identifier='userVar1' /><get-global identifier='userVar2' out-identifier='alternativeUserVar2'/></batch-execution>

<batch-execution><query out-identifier='cars' name='cars'/><query out-identifier='cars2' name='carsWithParams'><string>red</string><string>blue</string></query></batch-execution>

<batch-execution><startProcess processId='org.drools.actions'><parameter identifier='person'><org.drools.TestVariable><name>John Doe</name></org.drools.TestVariable></parameter></startProcess></batch-execution

JBoss Rules 5 リファレンスガイドリファレンスガイド

92

Page 97: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

9. signal event コマンドでプロセスの特定が可能になります。

10. complete work item コマンドは、プロセスが完了するとユーザーに通知します。

11. abort work item コマンドで、実行中にプロセスを取り消すことができます。

バグを報告する

11.17. MARSHALLERFACTORY

MarshallerFactory は、ステートフルナレッジセッションのマーシャリングとアンマーシャリングに使用します。

バグを報告する

11.18. マーシャラーの例

以下は、実際のマーシャーラーの例です。

バグを報告する

11.19. マーシャリングのオプション

表表11.1 マーシャリングのオプションマーシャリングのオプション

オプションオプション 説明説明

ObjectMarshallingStrategy このインターフェースは、マーシャリングの実装用に提供され、柔軟性が増します。

<signal-event process-instance-id='1' event-type='MyEvent'><string>MyValue</string></signal-event>

<complete-work-item id='" + workItem.getId() + "' ><result identifier='Result'><string>SomeOtherString</string></result></complete-work-item>

<abort-work-item id='21' />

// ksession is the StatefulKnowledgeSession// kbase is the KnowledgeBaseByteArrayOutputStream baos = new ByteArrayOutputStream();Marshaller marshaller = MarshallerFactory.newMarshaller( kbase );marshaller.marshall( baos, ksession );baos.close();

第第11章章 モードとメソッドモードとメソッド

93

Page 98: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

SerializeMarshallingStrategy これは、ユーザーインターフェースで Serializable または Externalizable メソッドを呼び出すデフォルトのストラテジです。

IdentityMarshallingStrategy このストラテジは、各ユーザーオブジェクトに整数の id を作成してマップに格納し、この id はストリームに書き込まれます。

アンマーシャリングすると、IdentityMarshallingStrategy マップにアクセスしてインスタンスを取得します。つまり、IdentityMarshallingStrategy を使用する場合、Marshaller インスタンスが存続する間ステートフルで、ID を作成してマーシャルしようとするオブジェクトすべてに対する参照を保持します。

オプションオプション 説明説明

バグを報告する

11.20. IDENTITYMARSHALLINGSTRATEGY の例

以下は、IdentityMarshallingStrategy を使用するためのコード例です。

バグを報告する

11.21. OBJECTMARSHALLINGSTRATEGYACCEPTOR

ObjectMarshallingStrategyAcceptor は、オブジェクトのマーシャリング戦略に含まれるインターフェースです。ユーザーオブジェクトの読み取りまたは書き込みを試行すると、ObjectMarshallingStrategyAcceptor を使用してユーザーオブジェクトのマーシャリングに使用されるかどうか決定するために使用します。

バグを報告する

11.22. CLASSFILTERACCEPTOR の実装

ClassFilterAcceptor の実装は、文字列やワイルドカードを使用してクラス名の照合ができるようにします。デフォルトは "*.*" です。

バグを報告する

11.23. アクセプターを使用した IDENTITYMARSHALLINGSTRATEGY の例

ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectMarshallingStrategy oms = MarshallerFactory.newIdentityMarshallingStrategy()Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[]{ oms } );marshaller.marshall( baos, ksession );baos.close();

JBoss Rules 5 リファレンスガイドリファレンスガイド

94

Page 99: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

以下は、アクセプターと IdentityMarshallingStrategy を使用した例です。承諾確認の順番は提供された配列の自然な順番で行われている点に注意してください。

バグを報告する

11.24. JBOSS RULES の永続性とトランザクション

JBoss Rules では、Java Persistence API (JPA) を使用して、カスタマイズなしで長期的に永続性を保つことができます。Java Transaction API (JTA) の実装をインストールする必要があります。設定が簡単で埋め込みに対応しているため、開発目的では Bitronix Transaction Manager を使用することができます。実稼働環境では、JBoss Transactions を推奨しています。

バグを報告する

11.25. トランザクション例

以下は、トランザクションの実行がどのように行われるか示しています。

バグを報告する

ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectMarshallingStrategyAcceptor identityAcceptor = MarshallerFactory.newClassFilterAcceptor( new String[] { "org.domain.pkg1.*" } );ObjectMarshallingStrategy identityStrategy = MarshallerFactory.newIdentityMarshallingStrategy( identityAcceptor );ObjectMarshallingStrategy sms = MarshallerFactory.newSerializeMarshallingStrategy();Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[]{ identityStrategy, sms } );marshaller.marshall( baos, ksession );baos.close();

Environment env = KnowledgeBaseFactory.newEnvironment();env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory( "emf-name" ) );env.set( EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager() ); // KnowledgeSessionConfiguration may be null, and a default will be usedStatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );int sessionId = ksession.getId(); UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" );ut.begin();ksession.insert( data1 );ksession.insert( data2 );ksession.startProcess( "process1" );ut.commit();

第第11章章 モードとメソッドモードとメソッド

95

Page 100: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

11.26. JPA の使用

手順手順11.2 タスクタスク

1. 環境は EntityManagerFactory と TransactionManager の両方で設定するようにします。

2. GUI またはコマンドから JPA を起動します。

3. ID を使用して以前に永続化したステートフルナレッジセッションをロードします。ロールバックが発生すると ksession のステートもロールバックされるため、ロールバック後もそのまま使用を続けることができます。

バグを報告する

11.27. JPA を持つ STATEFULKNOWLEDGESESSION のロード

以下は、JPA を実装する StatefulKnowledgeSession をロードするコードです。

バグを報告する

11.28. JPA の設定

永続性を有効にするには、以下の例のように複数のクラスを persistence.xml に追加する必要があります。

StatefulKnowledgeSession ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( sessionId, kbase, null, env );

<persistence-unit name="org.drools.persistence.jpa" transaction-type="JTA"><provider>org.hibernate.ejb.HibernatePersistence</provider><jta-data-source>jdbc/BitronixJTADataSource</jta-data-source><class>org.drools.persistence.session.SessionInfo</class><class>org.drools.persistence.processinstance.ProcessInstanceInfo</class><class>org.drools.persistence.processinstance.ProcessInstanceEventInfo</class><class>org.drools.persistence.processinstance.WorkItemInfo</class><properties><property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/><property name="hibernate.max_fetch_depth" value="3"/><property name="hibernate.hbm2ddl.auto" value="update" /><property name="hibernate.show_sql" value="true" /><property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" /></properties></persistence-unit>

JBoss Rules 5 リファレンスガイドリファレンスガイド

96

Page 101: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

11.29. JTA DATASOURCE の設定

如何は、JTA DataSource の設定コードです。

バグを報告する

11.30. JNDI プロパティ

Bitronix は単純な埋め込み JNDI サービスを提供しますが、これはテスト目的で理想的です。使用するには、jndi.properties ファイルを META-INF に追加して、以下の行をそのファイルに追加します。

バグを報告する

11.31. KNOWLEDGEBASE 名前空間

以下は、構築目的で KnowledgeBase に追加できる名前空間のリストです。

deftemplate

defrule

deffunction

and/or/not/exists/test 条件要素

Literal、Variable、Return Value および Predicate フィールド制約

バグを報告する

PoolingDataSource ds = new PoolingDataSource();ds.setUniqueName( "jdbc/BitronixJTADataSource" );ds.setClassName( "org.h2.jdbcx.JdbcDataSource" );ds.setMaxPoolSize( 3 );ds.setAllowLocalTransactions( true );ds.getDriverProperties().put( "user", "sa" );ds.getDriverProperties().put( "password", "sasa" );ds.getDriverProperties().put( "URL", "jdbc:h2:mem:mydb" );ds.init();

java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory

第第11章章 モードとメソッドモードとメソッド

97

Page 102: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第12章 USING SPREADSHEET DECISION TABLES

12.1. ハードキーワード

ハードキーワードは、ルールテキストで使用されるドメインオブジェクト、プロパティ、関数、その他の要素をネーミングする際に使用できないワードのことです。ハードキーワードは、true、false などの単語ですが、コマンドとすぐに間違えられる可能性があります。

バグを報告する

12.2. ソフトキーワード

ソフトキーワードは、ドメインプロジェクト、プロパティ、メソッド、関数、その他の要素のネーミングに使用することができます。ルールエンジンは、それらのコンテキストを認識してそれに合わせて処理します。

バグを報告する

12.3. ソフトキーワードのリスト

lock-on-active

date-effective

date-expires

no-loop

auto-focus

activation-group

agenda-group

ruleflow-group

entry-point

duration

package

import

dialect

salience

enabled

attributes

rule

JBoss Rules 5 リファレンスガイドリファレンスガイド

98

Page 103: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

extend

when

then

template

query

declare

function

global

eval

not

in

or

and

exists

forall

accumulate

collect

from

action

reverse

result

end

over

init

バグを報告する

12.4. コメント

コメントとは、ルールエンジンが無視するテキストのセクションです。このセクションに遭遇した場合は省略されます。セマンティックコードブロック内にある場合 (ルールの RHS など) は例外です。

バグを報告する

第第12章章 USING SPREADSHEET DECISION TABLES

99

Page 104: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

12.5. 1 行コメントの例

これは、1 行コメントの例です。1 行コメントを作成するには、'//' を使用します。パーサーは、コメント記号と同じ行にあり、コメント記号より後ろに来るものをすべて無視します。

バグを報告する

12.6. 複数行コメントの例

これが複数行コメントの例です。この設定は、セマンティックコードブロックの内部、外部両方にあるテキストのブロックをコメントアウトします。

バグを報告する

12.7. エラーメッセージ

101: No viable alternative

パーサーが決定ポイントに到達したが選択肢を特定できない場合に表示されます。

[ERR 101] Line 3:2 no viable alternative at input 'WHEN'

このメッセージは、不正な場所に設定されているトークン WHEN (ハードキーワード) にパーサーが遭遇したこと (ルール名が抜けているため) を意味します。

[ERR 101] Line 0:-1 no viable alternative at input '<eof>' in rule simple_rule in pattern [name]

引用符、アポストロフィ、括弧が正しく挿入されていない (閉じられていない) ことを表します。

102: Mismatched input

現在の入力位置で終わるはずの特定のシンボルを、パーサーが探していることを示します。

[ERR 102] Line 0:-1 mismatched input '<eof>' expecting ')' in rule simple_rule in pattern [name]

不完全なルールステートメントが原因でこのエラーが発生しています。通常、0:-1 ポジションを取得すると、パーサーがソースの最後に到達したことを意味します。

rule "Testing Comments"when // this is a single line comment eval( true ) // this is a comment in the same line of a patternthen // this is a comment inside a semantic code blockend

rule "Test Multi-line Comments"when /* this is a multi-line comment in the left hand side of a rule */ eval( true )then /* and this is a multi-line comment in the right hand side of a rule */end

JBoss Rules 5 リファレンスガイドリファレンスガイド

100

Page 105: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

103: Failed predicate

False と評価された意味述語をバリデートしています。通常、これらの意味述語はソフトキーワードを特定する際に使用します。

104: Trailing semi-colon not allowed

このエラーは、式がセミコロンで完了してはいけない eval 句に関連しています。

105: Early Exit

recognizer が提示のキーワードに最低でも 1 回合致する必要のある文法のサブルールに到達したにも関わらず、サブルールに合致がありませんでした。

バグを報告する

12.8. パッケージ

パッケージとは、import や global などルールやその他関連するコンストラクトのコレクションのことです。パッケージメンバーは通常、HR ルールなどのように相互に関連しあっています。パッケージは名前空間を表し、名前空間はルールの集まりごとに一意に保つことが理想です。パッケージ名自体が名前空間で、ファイルやフォルダーには全く関係ありません。

複数のルールソースから各種ルールを組み立て、これらすべてのルールを格納する最上位のパッケージ設定を 1 つ持たせることができます (ルール組み立て時)。別の名前で宣言されているパッケージリソースは、同じものであってもマージすることはできません。しかし、単一の Rulebase には組み込みの複数パッケージを含めることができます。パッケージ宣言として同じファイル内にパッケージのルールをすべて含めるというのが一般的な構造です (これにより完全埋め込み式になります)。

バグを報告する

12.9. IMPORT ステートメント

Import ステートメントは Java の import ステートメントと同様に動作します。ルールで使用するオブジェクトに対して完全修飾パスとタイプ名を指定する必要があります。JBoss Rules は同じ名前の Javaパッケージとパッケージ java.lang からクラスを自動的にインポートします。

バグを報告する

12.10. GLOBAL の使用

Global を使用するには、以下を行う必要があります。

1. ルールファイルでグローバル変数を宣言してルールで使用します。以下に例を示します。

global java.util.List myGlobalList;

rule "Using a global"when eval( true )then myGlobalList.add( "Hello World" );end

第第12章章 USING SPREADSHEET DECISION TABLES

101

Page 106: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. ワーキングメモリでグローバル値を設定します。ワーキングメモリにファクトをアサートする前に、すべてのグローバル値を設定することが推奨されます。以下に例を示します。

バグを報告する

12.11. FROM 要素

from 要素は、グローバルとして Hibernate セッションを指定することができます。また名前付きのHibernate クエリからデータをプルすることも可能です。

バグを報告する

12.12. E-メールサービスでの GLOBAL の使用

手順手順12.1 タスクタスク

1. ルールエンジンを呼び出す統合コードを開きます。

2. emailService オブジェクトを取得してから、ワーキングメモリに設定します。

3. DRL で、emailService 型のグルーバルがあり、名前を "email" と指定することを宣言します。

4. ルールの結果で、email.sendSMS(number, message) などを使用することができます。

警告警告

グローバルはルール間でデータを共有するよう設計されておらず、このために使用すべきではありません。ルールは常に作業メモリーステータスに対して理由付けし、反応します。したがって、データをルール間で渡す場合は、データをファクトとして作業メモリーにアサートします。

重要重要

ルール内部からグローバル値を設定または変更しないでください。常にワーキングメモリーインターフェースを使用してアプリケーションから値を設定することが推奨されます。

バグを報告する

List list = new ArrayList();WorkingMemory wm = rulebase.newStatefulSession();wm.setGlobal( "myGlobalList", list );

JBoss Rules 5 リファレンスガイドリファレンスガイド

102

Page 107: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第13章 関数

13.1. 関数

関数 は、通常の Java クラスではなく、ルールソースファイルにセマンティックコードを入れる手段です。ルールで関数を使用する主な利点は、1 つの場所ですべてのロジックを保持することができる点です。必要に応じて関数を変更することができます。

関数は、ルールの結果 (then) 部分に対してアクションを呼び出す際に最も便利です (特に、その特定のアクションを繰り返して使用する場合)。

バグを報告する

13.2. 関数宣言の例

典型的な関数宣言は、以下のようになります。

注記注記

正確には Java の一部でないにも拘らず、function キーワードが使用されている点に注目してください。この関数へのパラメーターは、メソッドで定義されています。必要がなければパラメーターを設定する必要はありません。戻り型は通常のメソッドのように定義されます。

バグを報告する

13.3. 静的メソッドを使用する関数宣言の例

関数宣言の以下の例は、ヘルパークラス (Foo.hello()) の静的メソッドを示しています。JBossRules は、関数 import の使用に対応しているため、以下を入力するために必要なコードは、以下のコードのみです。

バグを報告する

13.4. 関数宣言呼び出しの例

関数が定義またはインポートされる方法を問わず、結果内またはセマンティックコードブロック内で名前で呼び出して関数を使用します。これについて以下に例を示しています。

function String hello(String name) { return "Hello "+name+"!";}

import function my.package.Foo.hello

rule "using a static function"when eval( true )then System.out.println( hello( "Bob" ) );end

第第13章章 関数関数

103

Page 108: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

13.5. 型宣言

型宣言には、ルールエンジンでの目的が主に 2 つあり、それは 1) 新しい型の宣言を許可することと、2) 型のメタデータの宣言を許可することです。

バグを報告する

13.6. 型宣言のロール

表表13.1 型宣言のロール型宣言のロール

ロールロール 説明説明

新しい型の宣言 JBoss Rules には、ファクトとしてプレーンな Javaオブジェクトが同梱されています。しかし、ルールエンジンに直接モデルを定義するには、新しい型を宣言することで定義できます。また、すでにドメインモデルが構築されている場合にも使用できますが、理由付けプロセスに主に使用する追加のエンティティをこのモデルに補足する必要があります。

メタデータの宣言 ファクトにはメタ情報を関連付けることができます。メタ情報の例には、ファクト属性で表現されないデータや、そのファクト型の全インスタンスで一貫しているデータが含まれます。このメタ情報はランタイム時にエンジンからクエリを受け、理由付けのプロセスで使用されます。

バグを報告する

13.7. 新しい型の宣言

declare のキーワード、その後にフィールドのリスト、キーワード end を使用して、新しい型を宣言します。新しいファクトにはフィールドのリストがなければならず、リストがない場合はエンジンはクラスパス内に既存のファクトがないか検索して、ファクトが見つからない場合はエラーが出されます。

バグを報告する

13.8. 新しいファクト型の宣言例

以下の例では、Address という新しいファクト型が使用されています。このファクト型には number、streetName、city の 3 つの属性が含まれています。各属性には、ユーザーが作成した他のクラスや以前に宣言されたファクト型といった有効な Java 型などが含まれています。

バグを報告する

declare Address number : int streetName : String city : Stringend

JBoss Rules 5 リファレンスガイドリファレンスガイド

104

Page 109: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

13.9. 新しいファクト型の宣言の追加例

このファクト型の宣言では、Person の例を使用しています。dateOfBirth は java.util.Date 型(Java API) で、address はファクト型 Address です。

バグを報告する

13.10. IMPORT の使用例

以下の例は、import 機能を使用して完全修飾クラス名を使用せずに済ませる方法を示しています。

バグを報告する

13.11. 生成された JAVA クラス

新しいファクト型を宣言すると、JBoss Rules は、ファクト型を表す Java クラスを実装するバイトコードを生成します。生成した Java クラスは、型定義に 1 対 1 の Java Bean マッピングを行います。

バグを報告する

13.12. 生成 JAVA クラスの例

以下は、Person ファクト型を使用した生成 Java クラスの例です。

declare Person name : String dateOfBirth : java.util.Date address : Addressend

import java.util.Date

declare Person name : String dateOfBirth : Date address : Addressend

public class Person implements Serializable { private String name; private java.util.Date dateOfBirth; private Address address;

// empty constructor public Person() {...}

// constructor with all fields public Person( String name, Date dateOfBirth, Address address ) {...}

// if keys are defined, constructor with keys public Person( ...keys... ) {...}

// getters and setters

第第13章章 関数関数

105

Page 110: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

13.13. ルールでの宣言型の使用例

生成クラスは単純な Java クラスであるため、他のファクトと同様に透過的にルールで使用できます。

バグを報告する

13.14. メタデータの宣言

メタデータは、JBoss Rules ではファクト型、ファクト属性、ルールなど複数の異なるコンストラクションに割り当てることができます。JBoss Rules は '@' マークを使用してメタデータを導入しますが、常に以下の形式を使用します。

括弧内の metadata_value はオプションです。

バグを報告する

13.15. メタデータ属性との連携

JBoss Rules では、任意のメタデータ属性を宣言できますが、一部はエンジンに対して特別な意味を持ち、一部はランタイム時の問い合わせに利用できます。また、JBoss Rules では、ファクト型とファクト属性両方に対してメタデータを宣言できます。ファクト型の属性の前に宣言されたメタデータはファクト型に割り当てられ、属性の後に宣言されたメタデータはその特定の属性に割り当てられます。

バグを報告する

13.16. ファクト型でのメタデータ属性の宣言例

以下は、ファクト型と属性のメタデータ属性を宣言する例です。このファクト型に対して宣言したメタデータが 2 つ (@author および @dateOfCreation) と名前属性に対して定義したメタデータが 2 つ(@key および @maxLength) あります。@key メタデータには必須の値がないため、括弧や値は省略されました。

// equals/hashCode // toString}

rule "Using a declared Type"when $p : Person( name == "Bob" )then// Insert Mark, who is Bob's manager. Person mark = new Person(); mark.setName("Mark"); insert( mark );end

@metadata_key( metadata_value )

import java.util.Date

declare Person

JBoss Rules 5 リファレンスガイドリファレンスガイド

106

Page 111: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

13.17. @POSITION 属性

@position 属性は、フィールドの位置を宣言するために使用し、デフォルトで宣言された順番よりも優先させることができます。これは、パターンでの位置制約に使用されます。

バグを報告する

13.18. @POSITION の例

以下は、@position 属性の使用例です。

バグを報告する

13.19. 事前定義済みのクラスレベルアノテーション

表表13.2 事前定義済みのクラスレベルアノテーション事前定義済みのクラスレベルアノテーション

アノテーションアノテーション 説明説明

@role( <fact | event> ) この属性は、ファクトやイベントにロールを割り当てる際に使用します。

@typesafe( <boolean> ) デフォルトでは、型安全が有効な状態ですべての型宣言はコンパイルされています。@typesafe( false ) は、型安全ではない評価 (すべての制約が、MVEL 制約として生成され動的に実行される) へのフォールバックを許可してこの動作をオーバーライドする手段を提供します。これは、一般的な型コレクションや型が混合されているコレクションを処理する際に便利です。

@timestamp( <attribute name> ) タイムスタンプを作成します。

@duration( <attribute name> ) 属性の実装期間を設定します。

@expires( <time interval> ) 属性が失効する時間を定義することができます。

@author( Bob ) @dateOfCreation( 01-Feb-2009 )

name : String @key @maxLength( 30 ) dateOfBirth : Date address : Addressend

declare Cheese name : String @position(1) shop : String @position(2) price : int @position(0)end

第第13章章 関数関数

107

Page 112: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

@propertyChangeSupport Javabean 仕様に定義されているプロパティの変更のサポートを実装するファクトをアノテーションで追加できるようになり、エンジン自体がファクトプロパティでの変更をリッスンできるようになっています。

@propertyReactive 型プロパティを反応型にします。

アノテーションアノテーション 説明説明

バグを報告する

13.20. @KEY 属性関数

キー属性として属性を宣言すると、主に生成型に 2 種類の影響があります。

1. この属性はその型のキー識別子として使用されるため、生成クラスは、この型のインスタンスを比較する際にはこの属性を考慮に入れて、equals() と hashCode() メソッドを実装します。

2. JBoss Rules は、すべてのキー属性をパラメーターとして使用してコンストラクターを生成します。

バグを報告する

13.21. @KEY 宣言の例

以下は、型に対する @key 宣言の例です。JBoss Rules は、equals() と hashCode() メソッドを生成し、firstName と lastName 属性をチェックして Person の 2 つのインスタンスがそれぞれ同じであるかを判断します。ただし、age 属性はチェックしません。firstName と lastName をパラメーターとして取ることでコンストラクターも生成します。

バグを報告する

13.22. キーコンストラクターでのインスタンスの作成例

以下は、キーコンストラクターを使用してインスタンスを作成する例です。

バグを報告する

13.23. 位置引数

パターンは型宣言への位置引数をサポートし、@position 属性で定義されます。

declare Person firstName : String @key lastName : String @key age : intend

Person person = new Person( "John", "Doe" );

JBoss Rules 5 リファレンスガイドリファレンスガイド

108

Page 113: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

位置引数は、フィールド名を指定する必要がない場合に既知の名前付きフィールドへの位置マッピングを行います (つまり、Person( name == "mark" ) は Person( "mark"; ) で書き換えることができます)。エンジンが位置引数の前のすべてのアイテムを把握するようにするため、セミコロン ';' は重要です。セミコロン ';' で区切ることで、パターンに位置引数と名前引数の両方を併用することができます。バインドされていない位置で使用する変数は、フィールドにバインドされその位置にマッピングされます。

バグを報告する

13.24. 位置引数の例

以下の例を見てみましょう。

デフォルトの順番は宣言の順番ですが、@position を使用してオーバーライドできます。

バグを報告する

13.25. @POSITION アノテーション

@Position アノテーションは、クラスパスの元の POJO にアノテーションをつけるために使用できます。現在、クラスのフィールドのみアノテーションをつけることができます。クラスの継承に対応していますが、メソッドのインターフェースには対応していません。

バグを報告する

13.26. パターンの例

これらのパターンの例には、2 つの制約とバインディングが含まれています。セミコロン ';' を使用して、位置のセクションと名前の引数のセクションを分けています。リテラルのみを使用する変数、リテラル、式は対応していますが、変数を使用したものには対応していません。

バグを報告する

declare Cheese name : String shop : String price : intend

declare Cheese name : String @position(1) shop : String @position(2) price : int @position(0)end

Cheese( "stilton", "Cheese Shop", p; )Cheese( "stilton", "Cheese Shop"; p : price )Cheese( "stilton"; shop == "Cheese Shop", p : price )Cheese( name == "stilton"; shop == "Cheese Shop", p : price )

第第13章章 関数関数

109

Page 114: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第14章 その他の宣言

14.1. 既存のタイプのメタデータの宣言

JBoss Rules では、新しいファクト型に対してメタデータ属性を宣言する場合と同様に既存の型のメタデータ属性を宣言できます。唯一の相違点は、その宣言にフィールドがないことです。

バグを報告する

14.2. 既存型へのメタデータの宣言例

以下の例は、既存の型にメタデータを宣言する方法を示しています。

バグを報告する

14.3. 完全修飾クラス名を使用したメタデータの宣言例

以下の例は、import アノテーションではなく、完全修飾クラス名を使用してメタデータを宣言する方法を示しています。

バグを報告する

14.4. 宣言型に対してパラメーター化されたコンストラクトの例

宣言型:

コンパイラーは、暗黙的に 3 つのコンストラクターを生成します。1 つはパラメーターなし、1 つは@key フィールドのあるもの、1 つはすべてフィールドのあるものです。

バグを報告する

import org.drools.examples.Person

declare Person @author( Bob ) @dateOfCreation( 01-Feb-2009 )end

declare org.drools.examples.Person @author( Bob ) @dateOfCreation( 01-Feb-2009 )end

declare Person firstName : String @key lastName : String @key age : intend

Person() // parameterless constructorPerson( String firstName, String lastName )Person( String firstName, String lastName, int age )

JBoss Rules 5 リファレンスガイドリファレンスガイド

110

Page 115: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

14.5. 型安全でないクラス

@typesafe( <boolean>) アノテーションが型宣言に追加されています。デフォルトでは、すべての型宣言は型安全が有効な状態でコンパイルされています。@typesafe( false ) は、型安全ではない評価 (すべての制約が、MVEL 制約として生成され動的に実行される) へのフォールバックを許可してこの動作をオーバーライドする手段を提供します。これは、一般的な型コレクションや型が混合されているコレクションを処理する際に便利です。

バグを報告する

14.6. アプリケーションコードからの宣言済みタイプへのアクセス

アプリケーションは時には、宣言型からファクトにアクセスして処理する必要があります。このような場合、JBoss Rules はアプリケーションが実行する最も一般的なファクト処理に対して簡素化されたAPI を提供します。宣言ファクトはそのファクトが宣言されたパッケージに所属します。

バグを報告する

14.7. 型の宣言

以下は、型を宣言するプロセスについて例示しています。

バグを報告する

14.8. API を使用して宣言されたファクト型を処理する例

以下の例では、API で宣言されたファクト型を処理しています。

package org.drools.examples

import java.util.Date

declare Person name : String dateOfBirth : Date address : Addressend

// get a reference to a knowledge base with a declared type:KnowledgeBase kbase = ...

// get the declared FactTypeFactType personType = kbase.getFactType( "org.drools.examples", "Person" );

// handle the type as necessary:// create instances:Object bob = personType.newInstance();

// set attributes valuespersonType.set( bob, "name", "Bob" );personType.set( bob,

第第14章章 その他の宣言その他の宣言

111

Page 116: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

14.9. 型宣言の EXTENDS

型宣言は継承用に "extends" というキーワードをサポートしています。DRL 宣言のサブタイ部で Javaで宣言された型を継承するには、フィールドなしの宣言ステートメントでスーパータイプを繰り返します。

バグを報告する

14.10. 型宣言の EXTENDS 例

以下では、extends アノテーションの使用例を示しています。

バグを報告する

14.11. TRAIT

Traits により、クラス階層に自然に当てはまらない複数の動的な型をモデル化することができます。trait は、ランタイム時に個別のオブジェクトに適用できる (最終的に削除) インターフェースです。インターフェースから trait を作成するには、@format(trait) アノテーションを DRL の宣言に追加します。

バグを報告する

14.12. TRAIT の例

"age", 42 );

// insert fact into a sessionStatefulKnowledgeSession ksession = ...ksession.insert( bob );ksession.fireAllRules();

// read attributesString name = personType.get( bob, "name" );int age = personType.get( bob, "age" );

import org.people.Person

declare Personend

declare Student extends Person school : Stringend

declare LongTermStudent extends Student years : int course : Stringend

JBoss Rules 5 リファレンスガイドリファレンスガイド

112

Page 117: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Trait をオブジェクトに適用するには、新しい don キーワードを追加します。

バグを報告する

14.13. コアオブジェクトと TRAIT

コアオブジェクトが trait に don すると、プロキシクラスがオンザフライで作成されます (このようなクラスは、コア/trait クラスの組み合わせごとに遅延して生成されます)。コアオブジェクトをラップして trait インターフェースを実装するプロキシインスタンスは、自動的に挿入され、他のルールをアクティブ化することもあります。インターフェースの宣言と使用や実装プロキシをエンジンから解放する利点は、複数の継承階層がルール記述時に活用できる点です。しかし、コアクラスは静的にこれらのインターフェースを実装する必要がなく、コアとしてレガシークラスの使用がスムーズに行えるようにします。オブジェクトは trait を don することができます。ただし、効率の問題で、@Traitable アノテーションを宣言 bean クラスに追加して、コンパイラーが生成する必要のあるグルーコードの量を減らすことができます。これはオプションで、エンジンの動作を変更するわけではありません。

バグを報告する

14.14. @TRAITABLE の例

以下では、@Traitable アノテーションの使用例を示しています。

バグを報告する

14.15. TRAIT でのルールの記述

コアクラスと trait インターフェースは唯一プロキシレベルでつながっています (つまり、trait はコアクラスに特別に紐付けられているわけではありません)。つまり、同じ trait を完全に違うオブジェクトに適用することができます。こういった理由から、trait はコアオブジェクトのフォールドを透過的に公開しないのです。Trait インターフェースを使用してルールを記述すると、通常通りこのインターフェースのフィールドのみが利用できます。しかし、コアオブジェクトフィールドに該当するインターフェースのフィールドはプロキシクラスによりマッピングされます。

declare GoldenCustomer @format(trait) // fields will map to getters/setters code : String balance : long discount : int maxExpense : longend

when $c : Customer()then GoldenCustomer gc = don( $c, Customer.class );end

declare Customer @Traitable code : String balance : longend

第第14章章 その他の宣言その他の宣言

113

Page 118: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

14.16. TRAIT とルールの例

以下の例は、Trait インターフェースがフィールドにマッピングされる例です。

バグを報告する

14.17. 隠しフィールド

隠しフィールドとは、インターフェースに公開されていないコアクラスのフィールドです。

バグを報告する

14.18. 二部プロキシ (TWO-PART PROXY)

二部プロキシは、直感的に処理されないソフトフィールドや隠しフィールドを処理するために開発されました。内部ではプロキシは、適切なプロキシとラッパーで構成されています。プロキシはインターフェースを実装して、ラッパーはコアオブジェクトフィールドを管理し、名前/値マップをソフトフィールドにマッピングします。プロキシは必要に応じ、コアオブジェクトとマップラッパーの両方を使用してインターフェースを実装します。

バグを報告する

14.19. ラッパー

ラッパーは、ルール記述の際により疎性な型指定ができるようになります。しかし、他にも用途があります。ラッパーは、オブジェクトに追加された trait の数に拘らず、ラップするオブジェクトに固有のものとなります。同じオブジェクトのプロキシはすべて、同じラッパーを共有します。さらに、ラッパーには、ラップされたオブジェクトに添付されたプロキシすべてに対する後方参照が含まれており、trait がお互いを効果的に参照できるようにしています。

バグを報告する

14.20. ラッパーの例

以下は、ラッパーの使用例です。

when $o: OrderItem( $p : price, $code : custCode ) $c: GoldenCustomer( code == $code, $a : balance, $d: discount )then $c.setBalance( $a - $p*$d );end

when $sc : GoldenCustomer( $c : code, // hard getter $maxExpense : maxExpense > 1000 // soft getter )then $sc.setDiscount( ... ); // soft setterend

JBoss Rules 5 リファレンスガイドリファレンスガイド

114

Page 119: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

14.21. ISA アノテーションを使用したラッパー例

以下は、isA アノテーションを使ったラッパーの例です。

バグを報告する

14.22. TRAIT の削除

ビジネスロジックでは、ラップされたオブジェクトから trait を削除する必要がある場合もあります。削除の方法は 2 種類あります。

Logical don

Trait オペレーションを行うことでプロキシを論理的に挿入します。

shed キーワードキーワード

shed キーワードは、指定の引数型に該当するプロキシを削除します。

このオペレーションは、org.drools.factmodel.traits.Thing インターフェースを実装する別のプロキシを返します。ここでは、getFields() と getCore() メソッドが定義されます。内部では、宣言された trait がすべて生成されこのインターフェースを継承します (指定された他のインターフェースだけでなく)。こうすることで、通常はなくなってしまうソフトフィールドを持ったラッパーを保存することができます。

バグを報告する

14.23. ルール構文の例

以下は、ルール作成時に使用すべき構文の例を示しています。

$sc : GoldenCustomer( $maxExpense : maxExpense > 1000, this isA "SeniorCustomer")

then don( $x, // core object Customer.class, // trait class true // optional flag for logical insertion )

then Thing t = shed( $x, GoldenCustomer.class )

rule "<name>" <attribute>*when <conditional element>*then <action>*end

第第14章章 その他の宣言その他の宣言

115

Page 120: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

14.24. タイマー属性の例

以下は、timer 属性の例です。

バグを報告する

14.25. タイマー

以下は JBoss Rules で使用可能なタイマーです。

Interval

Interval ("int:" で指定) タイマーは、java.util.Timer オブジェクトのセマンティクスに従いますが、このタイマーは最初の遅延とオプションでその間隔を繰り返します。

Cron

Cron ("cron:" で指定) タイマーは標準の Unix cron 式に従います。

バグを報告する

14.26. CRON タイマーの例

以下は Cron タイマーの例です。

バグを報告する

14.27. カレンダー

カレンダーは、ルールが発火できるタイミングを制御する際に使用します。JBoss Rules は Quartz カレンダーを使用します。

バグを報告する

timer ( int: <initial delay><repeat interval>? )timer ( int: 30s )timer ( int: 30s 5m )

timer ( cron: <cron expression> )timer ( cron:* 0/15 * * * ? )

rule "Send SMS every 15 minutes" timer (cron:* 0/15 * * * ?)when $a : Alarm( on == true )then channels[ "sms" ].insert( new Sms( $a.mobileNumber, "The alarm is still on" );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

116

Page 121: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

14.28. QUARTZ カレンダーの例

以下は、Quartz カレンダーの例です。

バグを報告する

14.29. カレンダーの登録

手順手順14.1 タスクタスク

1. StatefulKnowledgeSession を開始します。

2. 以下のコードを使用してカレンダーを登録します。

3. カレンダーとタイマーを合わせて使用する場合、以下のコードを使用します。

バグを報告する

14.30. 左辺部 (LHS)

左辺部 (LHS: Left Hand Side) はルールの条件部分に使用される一般的な名前です。LHS は 0 個またそれ以上の条件要素で構成されます。LHS が空の場合、常に True となる条件要素として考慮され、新しい WorkingMemory セッションが作成されると 1 度だけアクティブ化されます。

バグを報告する

14.31. 条件の要素

Calendar weekDayCal = QuartzHelper.quartzCalendarAdapter(org.quartz.Calendar quartzCal)

ksession.getCalendars().set( "weekday", weekDayCal );

rule "weekdays are high priority" calendars "weekday" timer (int:0 1h)when Alarm()then send( "priority high - we have an alarm” );end

rule "weekend are low priority" calendars "weekend" timer (int:0 4h)when Alarm()then send( "priority low - we have an alarm” );end

第第14章章 その他の宣言その他の宣言

117

Page 122: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

条件要素は、1 つまたは複数のパターンパターンで動作します。最も一般的な条件要素は and で、何も接続されていないルールの LHS に複数のパターンがある場合、この条件要素は暗黙的に示されます。

バグを報告する

14.32. 条件要素なしのルールの例

以下は、条件要素がないルールの例です。

バグを報告する

rule "no CEs"when // emptythen ... // actions (executed once)end

// The above rule is internally rewritten as:

rule "eval(true)"when eval( true )then ... // actions (executed once)end

JBoss Rules 5 リファレンスガイドリファレンスガイド

118

Page 123: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第15章 パターン

15.1. パターン

パターン要素は、最も重要な条件要素です。ワーキングメモリに挿入された各ファクトにマッチする可能性があります。パターンには制約が含まれており、オプションでパターンのバインディングがあります。

バグを報告する

15.2. パターンの例

以下は、パターンの例です。

注記注記

and は、主導宣言バインディングを持つことができません。これは、宣言は 1 回に 1 つのファクトしか参照できないためで、and が満たされると両方のファクトと合致します。

バグを報告する

15.3. パターン一致

パターンは、指定の型のファクトと照合されます。この型は、ファクトオブジェクトの実際のクラスである必要はありません。パターンは、スーパークラスかインターフェースを参照でき、そこで違った種類のクラス多数からファクトが合致する可能性があります。制約は括弧内で定義されます。

バグを報告する

15.4. パターンのバインディング

パターンは、合致するオブジェクトにバインドすることができます。これは、$p などのパターンバインディング変数を使用することで可能です。

rule "2 unconnected patterns"when Pattern1() Pattern2()then ... // actionsend

// The above rule is internally rewritten as:

rule "2 and connected patterns"when Pattern1() and Pattern2()then ... // actionsend

第第15章章 パターンパターン

119

Page 124: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

15.5. 変数でバインドしたパターンの例

以下は、変数を使用したパターンバインディングの例です。

注記注記

接頭辞のドル記号 ($) は必須ではありません。

バグを報告する

15.6. 制約

制約は、true または false を返す式です。たとえば、5 は 6 よりも小さいという制約を指定することができます。

バグを報告する

rule ...when $p : Person()then System.out.println( "Person " + $p );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

120

Page 125: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第16章 要素と変数

16.1. JAVA BEAN でのプロパティアクセス (POJO)

bean プロパティは直接使用することができます。bean プロパティは、引数を取らずに何かを返す標準の Java bean ゲッター (getMyProperty() メソッド (またはプリミティブブール型 isMyProperty()) を使用して公開します。

JBoss Rules は標準の JDK Introspector クラスを使用して、このマッピングを行いますので、標準の Java bean 使用に準拠します。

警告警告

プロパティアクセサーは、ルールに影響を与える可能性のある形でオブジェクトのステータスを変更してはいけません。ルールエンジンは、呼び出しと呼び出しの間で合致した結果を効率的にキャッシュして処理を早めます。

バグを報告する

16.2. POJO の例

以下は、bean プロパティの例です。

age プロパティプロパティ

age プロパティは getAge() ゲッターの代わりに、DRL の age として記述します。

プロパティアクセサープロパティアクセサー

フィールドのインデックス化にによりパフォーマンスを向上するため、明示的にゲッター(getAge()) ではなくプロパティアクセス (age) を使用することができます。

バグを報告する

16.3. POJO との連携

手順手順16.1 タスクタスク

1. 以下の例を参照してください。

Person( age == 50 )

// this is the same as:Person( getAge() == 50 )

public int getAge() { Date now = DateUtil.now(); // Do NOT do this

第第16章章 要素と変数要素と変数

121

Page 126: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. これを解決するには、現在の日付をラップするファクトをワーキングメモリに挿入して、必要に応じて fireAllRules 間のファクトを更新します。

バグを報告する

16.4. POJO フォールバック

POJO と連携する場合 fallback メソッドが適用されます。プロパティのゲッターが見つからない場合、コンパイラーは、メソッド名にプロパティ名を引数なしで使用して再度ソートします。ネスト化したプロパティもインデックス化されます。

バグを報告する

16.5. フォールバックの例

以下は、フォールバック実装時にどのようになるかを示しています。

以下は、ネスト化したプロパティの場合どのようになるかを示しています。

警告警告

ステートフルセッションでは、ワーキングメモリはネスト化された値を認識せず、変化があっても分からないので、ネスト化されたアクセサーの使用時には注意が必要です。親参照がワーキングメモリに挿入される場合は、これらは不変であると考えてください。ネスト化された値を変更する場合、すべての外部ファクトは更新済みであるとマークする必要があります。上記の例では、houseNumber が変わると、その Address を持つ Person は更新済とマークする必要があります。

バグを報告する

16.6. JAVA 表現

表表16.1 Java 表現表現

return DateUtil.differenceInYears(now, birthday);}

Person( age == 50 )

// If Person.getAge() does not exists, this falls back to:Person( age() == 50 )

Person( address.houseNumber == 50 )

// this is the same as:Person( getAddress().getHouseNumber() == 50 )

JBoss Rules 5 リファレンスガイドリファレンスガイド

122

Page 127: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

機能機能 例例

パターンの括弧内にある制約として boolean を返す Java 表現を使用できます。Java 表現は、プロパティアクセスなど他の表現と合わせて利用することができます。

ロジックや数式のように括弧を使用して、評価優先度を変更することができます。

Java メソッドを再利用できます。

フィールドや値が違う型の場合、型強制が常に試行されます。不正に型の強制が行われると例外が送出されます。

警告警告

メソッドはルールに影響を与える可能性のある形式でオブジェクトのステータスを変更してはいけません。LHS のファクトで実行するメソッドは 読み取り専用の読み取り専用のメソッドでなければなりません。

警告警告

(これらのファクトが変更があるたびにワーキングメモリで更新済とマークされない限り) ファクトのステータスは、ルールの呼び出しと呼び出しの間で変更してはいけません。

Person( age == 50 )

Person( age > 100 && ( age % 10 == 0 ) )

Person( Math.round( weight / ( height * height ) ) < 25.0 )

Person( age == "10" ) // "10" is coerced to 10

Person( System.currentTimeMillis() % 1000 == 0 ) // Do NOT do this

第第16章章 要素と変数要素と変数

123

Page 128: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

重要重要

== と != 以外のすべての演算子は、通常の Java セマンティクスを使用します。

== 演算子は null セーフの equals() セマンティクスを持ちます。

!= 演算子は null セーフの !equals() セマンティクスを持ちます。

バグを報告する

16.7. コンマ区切りの演算子

コンマ文字 (',') は制約グループを区切るために使用し、この文字には暗黙的で接続的なセマンティクスがあります。

コンマ演算子は、読み取りがより簡単でエンジンが最適化できるため、上位の制約で使用されます。

バグを報告する

16.8. コンマ区切りの演算子例

以下は、暗黙的かつ接続的なセマンティクスを持つコンマ区切りのシナリオです。

注記注記

コンマ (,) 演算子は、括弧などの複合制約の表現に組み込むことはできません。

バグを報告する

16.9. バインド変数

JBoss Rules では変数にプロパティをバインドすることができます。こうすることで実行速度が早まりパフォーマンスを向上することができます。

// Similar to: java.util.Objects.equals(person.getFirstName(), "John")// so (because "John" is not null) similar to:// "John".equals(person.getFirstName())Person( firstName == "John" )

// Similar to: !java.util.Objects.equals(person.getFirstName(), "John")Person( firstName != "John" )

// Person is at least 50 and weighs at least 80 kgPerson( age > 50, weight > 80 )

// Person is at least 50, weighs at least 80 kg and is taller than 2 meter.Person( age > 50, weight > 80, height > 2 )

JBoss Rules 5 リファレンスガイドリファレンスガイド

124

Page 129: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.10. バインド変数の例

以下は、変数にバインドされたプロパティの例です。

注記注記

後方互換性の理由で、制約バインディングと制約表現を以下のように混合することが可能です (推奨はされていません)。

バグを報告する

16.11. ユニフィケーション

複数のプロパティの間で引数を統一化することができます。位置引数は常にユニフィケーションで処理され、名前付きの引数にはユニフィケーションの記号':=' が存在します。

バグを報告する

16.12. ユニフィケーションの例

以下は、2 つの引数を統一化した例です。

バグを報告する

16.13. JBOSS RULES のオプションと演算子

表表16.2 JBoss Rules のオプションと演算子のオプションと演算子

オプションオプション 説明説明 例例

// 2 persons of the same agePerson( $firstAge : age ) // bindingPerson( age == $firstAge ) // constraint expression

// Not recommendedPerson( $age : age * 2 < 100 )

// Recommended (separates bindings and constraint expressions)Person( age * 2 < 100, $age : age )

Person( $age := age ) Person( $age := age)

第第16章章 要素と変数要素と変数

125

Page 130: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

日付リテラル dd-mmm-yyyy の日付形式はデフォルトでサポートされています。drools.dateformat という名前の別の日付形式マスクを指定してカスタマイズすることができます。さらなる制御が必要な場合は制限を使用します。

List および Map アクセス インデックスにより List の値に直接アクセスできます。

値キー キーにより Map の値に直接アクセスできます。

略記組合せ比較条件 これは、&& または || を使用することでフィールドの制限を複数設置できるようになります。括弧を使ったグループ化も可能で、結果的に再帰的構文パターンになります。

オプションオプション 説明説明 例例

Cheese( bestBefore < "27-Oct-2009" )

// Same as childList(0).getAge() == 18Person( childList[0].age == 18 )

// Same as credentialMap.get("jsmith").isValid()Person( credentialMap["jsmith"].valid )

// Simple abbreviated combined relation condition using a single &&Person( age > 30 &&< 40 )

// Complex abbreviated combined relation using groupingsPerson( age ( (> 30 &&< 40) || (> 20 &&< 25) ) )

// Mixing abbreviated combined relation with constraint connectivesPerson( age > 30 &&< 40 || location == "london" )

JBoss Rules 5 リファレンスガイドリファレンスガイド

126

Page 131: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

演算子 演算子は、自然な順序でプロパティに対して使用することができます。例えば、日付フィールド <は String フィールドの 前前に来ます。アルファベット順でこちらのほうが早いためです。

演算子 matches 有効な Java regular expression とフィールドを照合します。通常、正規表現は文字列リテラルですが、有効な正規表現を解決する変数も使用可能です。String プロパティに対してのみ適用されます。null 値に matches を使用すると、常にfalse と評価されます。

演算子 not matches この演算子は、文字列が正規表現に一致しない場合に true を返します。同じルールは matches 演算子に適用されます。Stringプロパティにのみ適用されます。

演算子 contains contains の演算子は、 コレクションまたは配列に指定の値が含まれているかどうか確認するために使用します。Collection プロパティにのみ適用されます。

演算子 not contains not contains の演算子は、コレクションコレクションまたは配列に指定の値が含まれていないいないかどうか確認するために使用します。Collection プロパティにのみ適用されます。

オプションオプション 説明説明 例例

Person( firstName < $otherFirstName )

Person( birthDate < $otherBirthDate )

Cheese( type matches "(Buffalo)?\\S*Mozarella" )

Cheese( type not matches "(Buffulo)?\\S*Mozarella" )

CheeseCounter( cheeses contains "stilton" ) // contains with a String literalCheeseCounter( cheeses contains $var ) // contains with a variable

CheeseCounter( cheeses not contains "cheddar" ) // not contains with a String literalCheeseCounter( cheeses not contains $var ) // not contains with a variable

第第16章章 要素と変数要素と変数

127

Page 132: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

演算子 memberOf 演算子 memberOf は、フィールドがコレクションまたは配列のメンバーかどうかを確認するために使用します。コレクションは変数でなければなりません。

演算子 not memberOf 演算子 not memberOf は、フィールドがコレクションまたは配列のメンバーでないかどうかを確認するために使用します。コレクションは変数でなければなりません。

演算子 soundslike この演算子は matches に似ていますが、指定の値とよく似た音(英語の発音) であるかどうかを確認します。

演算子 str 演算子 str は、String のフィールドが特定の値で開始、終了するかどうかを確認するために使用します。文字列の長さを確認するためにも使用できます。

複合値制約 複合値制約は、合致する値が複数ある可能性がある場合に使用します。現在 in と not in のエバリュエーターのみがこれに対応しています。この演算子の 2 つ目のオペランドは、括弧でくくりコンマで区切った値のリストでなければなりません。値は変数、リテラル、戻り値、修飾 ID として指定できます。いずれのエバリュエーターも実は syntactic sugarで、!= および == の演算子を使用して複数の制限一覧を内部的に再度記述します。

オプションオプション 説明説明 例例

バグを報告する

CheeseCounter( cheese memberOf $matureCheeses )

CheeseCounter( cheese not memberOf $matureCheeses )

// match cheese "fubar" or "foobar"Cheese( name soundslike 'foobar' )

Message( routingValue str[startsWith] "R1" )

Message( routingValue str[endsWith] "R2" )

Message( routingValue str[length] 17 )

Person( $cheese : favouriteCheese )Cheese( type in ( "stilton", "cheddar", $cheese ) )

JBoss Rules 5 リファレンスガイドリファレンスガイド

128

Page 133: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

16.14. 演算子の優先順位

表表16.3 演算子の優先順位演算子の優先順位

演算子の型演算子の型 演算子演算子 備考備考

(ネスト化された) プロパティアクセス

. 通常の Java セマンティクスではない

List/Map アクセス [ ] 通常の Java セマンティクスではない

制約バインディング : 通常の Java セマンティクスではない

乗算 */%

加算 +-

変換 <<>>>>>

リレーショナル <><=>=instanceof

同等 ==!= 通常の Java (not) 同等同等 セマンティクスを使用せず、(not) 等等価価セマンティクスを使用します。

非短絡演算子 AND &

非短絡演算子の排他的論理和 OR ^

非短絡演算子の包含的論理和 OR |

論理積 AND &&

論理和 OR ||

三項演算子 ? :

コンマ区切りの AND , 通常の Java セマンティクスではない

バグを報告する

16.15. 粒度の高いプロパティ変更リスナー

これは、指定のパターン内に実際に制約またはバインドされたプロパティへの変更に対応するためだけのパターン合致機能です。これにより、擬似的なオブジェクトの分割を避け、パフォーマンスの向上と再帰をしやすくします。

第第16章章 要素と変数要素と変数

129

Page 134: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

デフォルトでは、ルールエンジンの動作が以前のリリースと後方互換を保つために、この機能はオフになっています。特定の bean でこの機能をアクティブ化するには、@propertyReactive のアノテーションをつける必要があります。

バグを報告する

16.16. 粒度の高いプロパティ変更リスナーの例

DRL の例の例

Java クラスの例クラスの例

バグを報告する

16.17. 粒度の高いプロパティ変更リスナーとの連携

このリスナーを使用すると、無限の反復を避けるために no-loop 属性を実装する必要がなくなります。エンジンは、ルールの RHS が他のプロパティを変更しつつ、プロパティ上でパターン合致が行われていることを認識します。Java クラスでは、呼び出しが実際に他のプロパティを変更したことを通知するために、メソッドのアノテーションも可能です。

バグを報告する

16.18. @WATCH でのパターンの使用

@watch のアノテーションをパターンにつけることで、プロパティの推論セットを変更してそのパターンを削除することができます。@watch アノテーションで名前が付けられたプロパティは、自動的に推論されたものに追加されます。! で名前を開始することで、1 つまたは複数のパターンを明示的に除外することができます。また、パターンの中で使用されているタイプのプロパティすべてをリッスンするまたはしないというパターンを指定するには、それぞれワイルドカード * および !* を使用します。

バグを報告する

16.19. @WATCH の例

以下は、ルールの LHS の @watch アノテーションです。

declare Person @propertyReactive firstName : String lastName : String end

@PropertyReactive public static class Person { private String firstName; private String lastName; }

JBoss Rules 5 リファレンスガイドリファレンスガイド

130

Page 135: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

@PropertyReactive のアノテーションがついた型を使用して、あるパターンにこのアノテーションを使用するのは意味がないため、ルールコンパイラーはコンパイルエラーを出します。また、@watch (例:@watch( firstName, ! firstName ) など) で同じプロパティを重複して使用するとコンパイルエラーが発生します。

バグを報告する

16.20. @PROPERTYSPECIFICOPTION の使用

デフォルトで @watch を有効にするか、KnowledgeBuilderConfiguration の on オプションを使用してこのアノテーションを利用できなくします。新しい PropertySpecificOption は、以下の 3 つの値を取ることができます。

バグを報告する

16.21. 基本的な条件要素

表表16.4 基本的な条件要素基本的な条件要素

名前名前 説明説明 例例 追加のオプション追加のオプション

// listens for changes on both firstName (inferred) and lastName Person( firstName == $expectedFirstName ) @watch( lastName )

// listens for all the properties of the Person bean Person( firstName == $expectedFirstName ) @watch( * )

// listens for changes on lastName and explicitly exclude firstName Person( firstName == $expectedFirstName ) @watch( lastName, !firstName )

// listens for changes on all the properties except the age one Person( firstName == $expectedFirstName ) @watch( *, !age )

- DISABLED => the feature is turned off and all the other related annotations are just ignored - ALLOWED => this is the default behavior: types are not property reactive unless they are not annotated with @PropertySpecific - ALWAYS => all types are property reactive by default

第第16章章 要素と変数要素と変数

131

Page 136: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

and 条件要素 and は、他の条件要素を組み合わせて論理的に連携します。JBoss Rules は接頭辞 and、接中辞 and の両方に対応しています。また、括弧で明示的にグループ化することもできます。また。従来の接中辞、接頭辞 and も使用できます。

接頭辞 and にも対応しています。

LHS の root 要素は暗黙的な接頭辞 and で、指定する必要はありません。

名前名前 説明説明 例例 追加のオプション追加のオプション

//infixAndCheese( cheeseType : type ) and Person( favouriteCheese == cheeseType )

//infixAnd with grouping( Cheese( cheeseType : type ) and ( Person( favouriteCheese == cheeseType ) or Person( favouriteCheese == cheeseType ) )

(and Cheese( cheeseType : type ) Person( favouriteCheese == cheeseType ) )

when Cheese( cheeseType : type ) Person( favouriteCheese == cheeseType )then ...

JBoss Rules 5 リファレンスガイドリファレンスガイド

132

Page 137: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

or これは、2 つ以上のよく似たルールを生成するショートカットです。JBoss Rules は接頭辞 or と接中辞 or の両方に対応しています。従来の接頭辞、接中辞、括弧の明示的グループ化を使用することができます。

オプションのパターンバインディングを可能にします。各パターンは、eponymous 変数を使用して、個別にバインドする必要があります。

名前名前 説明説明 例例 追加のオプション追加のオプション

//infixOrCheese( cheeseType : type ) or Person( favouriteCheese == cheeseType )

//infixOr with grouping( Cheese( cheeseType : type ) or ( Person( favouriteCheese == cheeseType ) and Person( favouriteCheese == cheeseType ) )

(or Person( sex == "f", age > 60 ) Person( sex == "m", age > 65 )

pensioner : ( Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 ) )

(or pensioner : Person( sex == "f", age > 60 ) pensioner : Person( sex == "m", age > 65 ) )

第第16章章 要素と変数要素と変数

133

Page 138: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

not これは、absent と指定されたオブジェクトがワーキングメモリに含まれていないことを確認します。適用される条件要素を囲む括弧が後にくる場合もあります (単一のパターンの場合は括弧を省略することができます)。

exists これは、指定のアイテムが存在するかどうか、ワーキングメモリをチェックします。適用される CE を囲む括弧がキーワード exists の後に来る必要があります(単一のパターンの場合は括弧を省略することができます)。

名前名前 説明説明 例例 追加のオプション追加のオプション

// Brackets are optional:not Bus(color == "red")// Brackets are optional:not ( Bus(color == "red", number == 42) )// "not" with nested infix and - two patterns,// brackets are requires:not ( Bus(color == "red") and Bus(color == "blue") )

exists Bus(color == "red")// brackets are optional:exists ( Bus(color == "red", number == 42) )// "exists" with nested infix and,// brackets are required:exists ( Bus(color == "red") and Bus(color == "blue") )

JBoss Rules 5 リファレンスガイドリファレンスガイド

134

Page 139: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

条件要素 or の動作は、フィールド制約の制約や制限に対する接続演算子 || とは違います。エンジンは、条件要素 or を解釈することができません。代わりに、or を持つルールは多くのサブルールで再記述されます。このプロセスは最終的に root ノードに or を1 つと CE ごとにサブルール 1 つ持つルールとなります。サブルールはそれぞれ通常のルールのようにアクティブ化して発火することができます。これらのサブルールの間での特別な動作や対話はありません。

バグを報告する

16.22. 条件要素 FORALL

この要素は、最初のパターンと合致したすべてのファクトが残りのパターンすべてと一致する場合、True と評価されます。これはスコープデリミタースコープデリミターです。そのため、以前にバインドされた変数を使用できますが、条件要素内にバインドされた変数は、要素の外側で使用することができません。

Forall は、他の条件要素内にネスト化することができます。例えば、forall は not 条件要素内で使用できます。単一パターンにはオプションで括弧が使用されますが、ネスト化された forall では括弧を必ず使用してください。

バグを報告する

16.23. FORALL の例

True に評価に評価

単一パターン単一パターン forall

複数パターン複数パターン forall

rule "All English buses are red"when forall( $bus : Bus( type == 'english') Bus( this == $bus, color = 'red' ) )then // all English buses are redend

rule "All Buses are Red"when forall( Bus( color == 'red' ) )then // all Bus facts are redend

rule "all employees have health and dental care programs"when forall( $emp : Employee() HealthCare( employee == $emp ) DentalCare( employee == $emp ) )

第第16章章 要素と変数要素と変数

135

Page 140: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ネスト化されたネスト化された forall

バグを報告する

16.24. 条件要素 FROM

条件要素 from は、LHS パターンと照合させる任意のデータのソースを指定できます。これにより、エンジンがワーキングメモリではなくデータから推論することができます。このデータソースは、バインド変数にあるサブフィールドか、メソッド呼び出しの結果のいずれかが可能です。他のアプリケーションのコンポーネントやフレームワークとカスタマイズなしに統合できる、力強い構造となっています。一般的な例として、hibernate の名前がついたクエリを使用して、データベースからオンデマンドででリトリーブしたデータと統合ができます。

オブジェクトソースを定義するために使用した表現は、通常の MVEL 構文に準拠しています。そのため、オブジェクトのプロパティナビゲーションを簡単に使用し、メソッドの呼び出しを行い、マップやコレクション要素へアクセスすることができます。

重要重要

lock-on-active と from を使用すると、ルールが発火されない可能性があります。

この問題に対処するには、複数の方法があります。

前ファクトをワーキングメモリーにアサートできる場合は from の使用をさけるか、制約表現でネスト化されたオブジェクト参照を使用します (以下参照)。

条件内 (LHS) の最後の文章として modify ブロックで使用するために割り当てられた変数を配置します。

同じ rule-flow グループでルールのアクティベーションをどのように行うか明示的に管理できる場合、lock-on-active を使用しないようにします。

バグを報告する

16.25. FROM の例

パターンでの推論およびバインディングパターンでの推論およびバインディング

then // all employees have health and dental careend

rule "not all employees have health and dental care"when not ( forall( $emp : Employee() HealthCare( employee == $emp ) DentalCare( employee == $emp ) ) )then // not all employees have health and dental careend

JBoss Rules 5 リファレンスガイドリファレンスガイド

136

Page 141: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

グラフ表記の使用グラフ表記の使用

すべてのオブジェクトで反復すべてのオブジェクトで反復

lock-on-active と併用と併用

バグを報告する

16.26. 条件要素 COLLECT

rule "validate zipcode"when Person( $personAddress : address ) Address( zipcode == "23920W") from $personAddress then // zip code is okend

rule "validate zipcode"when $p : Person( ) $a : Address( zipcode == "23920W") from $p.address then // zip code is okend

rule "apply 10% discount to all items over US$ 100,00 in an order"when $order : Order() $item : OrderItem( value > 100 ) from $order.itemsthen // apply discount to $itemend

rule "Assign people in North Carolina (NC) to sales region 1"ruleflow-group "test"lock-on-active truewhen $p : Person(address.state == "NC" ) then modify ($p) {} // Assign person to sales region 1 in a modify blockend

rule "Apply a discount to people in the city of Raleigh"ruleflow-group "test"lock-on-active truewhen $p : Person(address.city == "Raleigh" ) then modify ($p) {} //Apply discount to person in a modify blockend

第第16章章 要素と変数要素と変数

137

Page 142: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

条件要素 collect は、ルールが指定のソースかワーキングメモリーから取得したオブジェクトのコレクションから推測できるようにします。一階述語論理の用語では、これがカーディナリティ(cardinality) 数量子です。

java.util.Collection インターフェースを実装してデフォルトの no-arg パブリックコンストラクタを提供する具体的なクラスが、collect の結果パターンとなりえます。java.util.Collectionを実装してデフォルトの no-arg パブリックコンストラクタを提供する限り、ArrayList、LinkedList、HashSet などの Java コレクションや独自のクラスを使用することができます。

collect 条件要素の前にバインドされた変数は、ソースおよび結果パターンの両方のスコープ内であるため、これらを使用してお使いのソースや結果パターンを制約することができます。collect 内でバインドされた場合 collect 条件要素外では使用できません。

バグを報告する

16.27. 条件要素 ACCUMULATE

条件要素 accumulate は collect の機能だけでなく collect で達成できない結果を達成できるため、collect がより柔軟で力強くなったものであるといえます。オブジェクトのコレクションで反復して、各要素にカスタムのアクションを実行することができます。最終的に、結果オブジェクトを返します。

Accumulate は、事前定義済みの accumulate 関数もインラインのカスタムコードの使用にも対応しています。ただし、ルール作成者によるコードの管理が困難でコードの重複が頻繁に起こるため、インラインのカスタムコードは避けるべきです。Accumulate 関数のほうがテストや再利用も簡単です。

Accumulate 条件要素は、複数の違った構文にも対応しています。推奨されている構文は以下に記載のトップレベルの accumulate ですが、その他の構文にも後方互換を確保するため対応しています。

バグを報告する

16.28. 条件要素 ACCUMULATE の構文

トップレベルのトップレベルの accumulate 構文構文

構文の例構文の例

上記の例では、min、max、average が Accumulate 関数で、センサーが読み取ったすべての気温の値について最小値、最大値、平均値を算出します。

accumulate( <source pattern>; <functions> [;<constraints>] )

rule "Raise alarm"when $s : Sensor() accumulate( Reading( sensor == $s, $temp : temperature ); $min : min( $temp ), $max : max( $temp ), $avg : average( $temp ); $min < 20, $avg > 70 )then // raise the alarmend

JBoss Rules 5 リファレンスガイドリファレンスガイド

138

Page 143: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.29. 条件要素 ACCUMULATE の関数

average

min

max

count

sum

collectList

collectSet

これらの一般的な関数は入力値として任意の式を受け取ります。たとえば、注文した全アイテムの平均利益を計算する場合、以下のように average 関数を使用してルールを記述することができます。

バグを報告する

16.30. 条件要素 ACCUMULATE およびプラガビリティ

Accumulate 関数はすべてプラグインができます。つまり、必要であれば、カスタムのドメイン固有の関数を簡単にエンジンに追加でき、ルールは制限なしにすぐにそれらの関数を使用することができます。新しい Accumulate 関数を実装するには、org.drools.runtime.rule.TypedAccumulateFunction インターフェースを実装する Javaクラスを作成して設定ファイルに 1 行追加するか、エンジンに新しい関数を通知するためのシステムプロパティを設定します。

バグを報告する

16.31. 条件要素 ACCUMULATE とプラガビリティの例

Accumulate 関数の実装例として、以下に average 関数の実装を示しています。

rule "Average profit"when $order : Order() accumulate( OrderItem( order == $order, $cost : cost, $price : price ); $avgProfit : average( 1 - $cost / $price ) )then // average profit for $order is $avgProfitend

/** * An implementation of an accumulator capable of calculating average values */public class AverageAccumulateFunction implements org.drools.runtime.rule.TypedAccumulateFunction {

第第16章章 要素と変数要素と変数

139

Page 144: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

}

public void writeExternal(ObjectOutput out) throws IOException {

}

public static class AverageData implements Externalizable { public int count = 0; public double total = 0; public AverageData() {}

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { count = in.readInt(); total = in.readDouble(); }

public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(count); out.writeDouble(total); }

}

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#createContext() */ public Serializable createContext() { return new AverageData(); }

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object) */ public void init(Serializable context) throws Exception { AverageData data = (AverageData) context; data.count = 0; data.total = 0; }

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#accumulate(java.lang.Object, java.lang.Object) */ public void accumulate(Serializable context, Object value) { AverageData data = (AverageData) context; data.count++;

JBoss Rules 5 リファレンスガイドリファレンスガイド

140

Page 145: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.32. 条件要素 ACCUMULATE 関数のコード

プラグイン関数のコードプラグイン関数のコード (設定ファイルに入力設定ファイルに入力)

その他の構文:戻り型を持つ単一関数その他の構文:戻り型を持つ単一関数

data.total += ((Number) value).doubleValue(); }

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object) */ public void reverse(Serializable context, Object value) throws Exception { AverageData data = (AverageData) context; data.count--; data.total -= ((Number) value).doubleValue(); }

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object) */ public Object getResult(Serializable context) throws Exception { AverageData data = (AverageData) context; return new Double( data.count == 0 ? 0 : data.total / data.count ); }

/* (non-Javadoc) * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse() */ public boolean supportsReverse() { return true; }

/** * {@inheritDoc} */ public Class< ? > getResultType() { return Number.class; }

}

jbossrules.accumulate.function.average = org.jbossrules.base.accumulators.AverageAccumulateFunction

rule "Apply 10% discount to orders over US$ 100,00"

第第16章章 要素と変数要素と変数

141

Page 146: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.33. インライン式のカスタムコードを使用した ACCUMULATE

警告警告

インライン式のカスタムコードと accumulate を使用するのは、これを使うルールの保守とテストが困難でコードの再利用ができないなど、複数の理由により適切とは言えません。独自の accumulate 関数を実装することで、テストが簡素化されます。この形式の accumulate は後方互換用にサポートされています。

インライン式のカスタムコードを使用した accumulate 条件要素の一般的な構文は以下のとおりです。

以下に、各要素の意味を説明をしています。

<source pattern>: このソースパターンは、エンジンがソースオブジェクトと照合する際の通常のパターンのことです。

<init code> : これは、選択したダイアレクトのコードのセマンティックブロックであり、ソースオブジェクトに対する繰り返し処理が行われる前に各 Tuple に対して一度実行されます。

<action code>: これは、選択したダイアレクトのコードのセマンティックブロックであり、各ソースオブジェクトに対して実行されます。

<reverse code>: これは選択したダイアレクトのコードのセマンティックブロック (任意) で、これが指定されている場合はソースパターンに合致しなくなった各ソースオブジェクトに対して実行されます。このコードブロックの目的は、ソースオブジェクトが変更または削除された際にエンジンがデクリメント演算を実行できるように <action code> ブロックで行われた演算を元に戻すことでこれらの演算を大幅に改善することです。

when $order : Order() $total : Number( doubleValue > 100 ) from accumulate( OrderItem( order == $order, $value : value ), sum( $value ) )then # apply discount to $orderend

<result pattern>from accumulate(<source pattern>,init(<init code>),action(<action code>),reverse(<reverse code>),result(<result expression>) )

JBoss Rules 5 リファレンスガイドリファレンスガイド

142

Page 147: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

<result expression>: これは選択したダイアレクトのセマンティック式で、すべてのソースオブジェクトに対して繰り返し処理が実行された後に実行されます。

<result pattern>: <result expression> から返されたオブジェクトに対してエンジンが照合を行う通常のパターンです。合致があると、accumulate 条件要素は true と評価され、エンジンはルール内の次の条件要素を評価に進みます。合致がない場合は、accumulate 条件要素がfalse と評価され、エンジンはそのルールの条件要素の評価を終了します。

バグを報告する

16.34. インライン式のカスタムコードを使用した ACCUMULATE の例

インライン式のカスタムコードインライン式のカスタムコード

上記の例では、ワーキングメモリーの各 Order に対してエンジンは init code を実行してすべての変数をゼロに初期化します。次に、その順番で OrderItem オブジェクトすべてで反復を行い、それぞれに対してアクションアクションを実行します (この例では、全アイテムの値を合計して total 変数にします)。全 OrderItem オブジェクトで反復した後、result expression に該当する値を返します (上記の例では変数 total の値)。最後に、エンジンはその結果と Number パターンを照合して、doublevalue が 100 以上であればルールが発火されます。

カスタムオブジェクトのインスタンス化と生成カスタムオブジェクトのインスタンス化と生成

rule "Apply 10% discount to orders over US$ 100,00"when $order : Order() $total : Number( doubleValue > 100 ) from accumulate( OrderItem( order == $order, $value : value ), init( double total = 0; ), action( total += $value; ), reverse( total -= $value; ), result( total ) )then # apply discount to $orderend

rule "Accumulate using custom objects"when $person : Person( $likes : likes ) $cheesery : Cheesery( totalAmount > 100 ) from accumulate( $cheese : Cheese( type == $likes ), init( Cheesery cheesery = new Cheesery(); ), action( cheesery.addCheese( $cheese ); ), reverse( cheesery.removeCheese( $cheese ); ), result( cheesery ) );then // do somethingend

第第16章章 要素と変数要素と変数

143

Page 148: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.35. 条件要素 EVAL

条件要素 eval は基本的にキャッチオールの条件要素で、どのセマンティックコードでも実行できます(プリミティブブール型を返します)。このコードは、ルールの LHS でバインドされた変数とルールパッケージの関数を参照できます。eval を使用しすぎると、ルールの宣言性が減少しエンジンのパフォーマンスが下がる可能性があります。eval はパターンのどこでも使用できますが、ベストプラクティスはルールの LHS 内で最後の条件要素として追加することです。

eval はインデックス化ができないため、フィールド制約ほど効率的ではありません。しかし、関数が時間をかけて変化する値を返す場合などフィールド制約では許容できないため、このような場合は evalの使用が理想的です。

バグを報告する

16.36. 条件要素 EVAL の例

以下は eval の使用例です。

バグを報告する

16.37. 右辺部 (RHS)

右辺部 (RHS: Right Hand Side) はルールの結果またはアクション部を指す一般的な名称でうs。RHS の主な目的は、ワーキングメモリーのデータを挿入、削除、変更することです。この部分には、実行するアクションのリストを含める必要があります。ルールの RHS 部は小さく保つことで、宣言性を確保して読み取りやすくします。

注記注記

RHS に命令および条件コードが必要な場合、複数のルールに分割します。

バグを報告する

16.38. RHS コンビニエンスメソッド

表表16.5 RHS コンビニエンスメソッドコンビニエンスメソッド

名前名前 説明説明

p1 : Parameter()p2 : Parameter()eval( p1.getList().containsKey( p2.getItem() ) )

p1 : Parameter()p2 : Parameter()// call function isValid in the LHSeval( isValid( p1, p2 ) )

JBoss Rules 5 リファレンスガイドリファレンスガイド

144

Page 149: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

update(object, handle); エンジンにオブジェクトが変更し (LHS で何かにバインドされているたもの)、ルールを再検討する必要があると通知します。

update(object); update() を使用して、ナレッジヘルパーは渡されたオブジェクトのアイデンティティチェックをしてfacthandle を検索します (エンジンに挿入する Javabean にプロパティ変更リスナーを渡した場合、オブジェクトの変更があっても update() を呼び出す必要はありません)。ファクトのフィールド値が変更すると、他のファクトを変更する前に update を呼び出す必要があります。呼び出さないと、ルールエンジン内のインデックス化に問題が出てくる可能性があります。modify キーワードを使用することでこの問題を回避できます。

insert(newobject()); 独自に作成した新しいオブジェクトをワーキングメモリーに設定します。

insertLogical(newobject()); 挿入に似ていますが、現在ルールを発火している真理をサポートするファクトがこれ以上ない場合、オブジェクトは自動的に削除されます

retract(handle); ワーキングメモリーからオブジェクトを削除します。

名前名前 説明説明

バグを報告する

16.39. DROOLS 変数を使用したコンビニエンスメソッド

drools.halt() の呼び出しはルール実行をすぐに中断します。現在のセッションが fireUntilHalt() と連携していた時点に制御を戻すために必要です。

insert(Object o)、update(Object o)、retract(Object o) メソッドは drools でも呼び出されますが、頻繁に使用されるためオブジェクト参照なしで呼び出すことができます。

drools.getWorkingMemory() は WorkingMemory オブジェクトを返します。

drools.setFocus( String s) は指定のアジェンダグループにフォーカスを設定します。

ルールの RHS から呼び出された drools.getRule().getName() はルールの名前を返します。

drools.getTuple() は現在実行中のルールと合致する Tuple を返し、drools.getActivation() は該当するアクティベーションを行います (これらの呼び出しはロギングやデバッグ目的に便利です)。

バグを報告する

第第16章章 要素と変数要素と変数

145

Page 150: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

16.40. KCONTEXT 変数を使用したコンビニエンスメソッド

kcontext.getKnowledgeRuntime().halt() の呼び出しはルールの実行を即座に終了します。

getAgenda() アクセサーは、セッションの Agenda への参照を返し、順番に様々なルールグループ (アクティベーショングループ、アジェンダグループ、ルールフローグループ) へアクセスできるようにします。一般的な例はアジェンダグループの一部をアクティブ化することで、これは長めの呼び出しで可能になります。

(drools.setFocus( "CleanUp" ) を使用しても同じことが行えます)

クエリを実行するには getQueryResults(String query) を呼び出し、そこで結果を処理することができます。

イベント管理を処理するメソッドは、ワーキングメモリーやアジェンダに対してイベントリスナーの追加や削除を可能にします。

getKnowledgeBase() メソッドは KnowledgeBase オブジェクト、システム内の全ナレッジのバックボーン、現在のセッションの開始元を返します。

setGlobal(...)、getGlobal(...)、getGlobals() で global を管理できます。

getEnvironment() メソッドはランタイムの Environment を返します。

バグを報告する

16.41. MODIFY ステートメント

表表16.6 modify ステートメントステートメント

名前名前 説明説明 構文構文 例例

// give focus to the agenda group CleanUpkcontext.getKnowledgeRuntime().getAgenda().getAgendaGroup( "CleanUp" ).setFocus();

JBoss Rules 5 リファレンスガイドリファレンスガイド

146

Page 151: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

modify これにより、fact を更新する際に構造化したアプローチを行うことができます。更新オペレーションと多くのセッター呼び出しを組み合わせてオブジェクトのフィールドを変更します。

括弧内の <fact-expression> は、ファクトのオブジェクト参照を生成する必要があります。ブロック内の表現リストには、通常のオブジェクト参照 (自動的にコンパイラーにより先頭に追加) なしに記述されるように指定のオブジェクトに対するセッター呼び出しを含めなければなりません。

名前名前 説明説明 構文構文 例例

バグを報告する

16.42. クエリーの例

注記注記

結果を返すには、ksession.getQueryResults("name") を使用します。"name" にはクエリーの名前が入ります。これは、クエリー結果のリストを返すため、クエリーに該当したオブジェクトを取得できます。

年齢年齢 30 を超える人に関するクエリーを超える人に関するクエリー

年齢が年齢が x を超え、を超え、y に住んでいる人に関するクエリーに住んでいる人に関するクエリー

バグを報告する

modify ( <fact-expression> ) {<expression> [ ,<expression> ]*}

rule "modify stilton"when $stilton : Cheese(type == "stilton")then modify( $stilton ){ setPrice( 20 ), setAge( "overripe" ) }end

query "people over the age of 30" person : Person( age > 30 )end

query "people over the age of x" (int x, String y) person : Person( age > x, location == y )end

第第16章章 要素と変数要素と変数

147

Page 152: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

16.43. QUERYRESULTS の例

標準の 'for' loop を使用して QueryResults を反復します。各要素は QueryResultsRow で、tuple の各列にアクセスする際に使用できます。これらの列は、バインドされた宣言名またはインデックスの位置によりアクセスできます。

バグを報告する

16.44. 他のクエリを呼び出すクエリ

クエリは他のクエリを呼び出すことができます。オプションのクエリ引数と組み合わせて、抽出クエリスタイルの後ろ向き連鎖を提供します。また、位置と名前付きを混ぜることも可能ですが、位置が先に来る必要があります (セミコロンで区切る)。リテラル表現はクエリ引数として渡すことが可能ですが、表現と変数を混合することはできません。

注記注記

このプロセスで '?' 記号を使用すると、クエリのみがプルされ、結果が返されると基盤のデータが変更してもこれ以上結果を受け取ることはありません。

バグを報告する

16.45. 他のクエリを呼び出すクエリ例

別のクエリを呼び出すクエリ別のクエリを呼び出すクエリ

ライブクエリを使用してクエリの結果から変更を徐々に反応的に受け取る例ライブクエリを使用してクエリの結果から変更を徐々に反応的に受け取る例

QueryResults results = ksession.getQueryResults( "people over the age of 30" );System.out.println( "we have " + results.size() + " people over the age of 30" );

System.out.println( "These people are are over 30:" );

for ( QueryResultsRow row : results ) { Person person = ( Person ) row.get( "person" ); System.out.println( person.getName() + "\n" );}

declare Location thing : String location : String end

query isContainedIn( String x, String y ) Location(x, y;) or ( Location(z, y;) and ?isContainedIn(x, z;) )end

query isContainedIn( String x, String y ) Location(x, y;)

JBoss Rules 5 リファレンスガイドリファレンスガイド

148

Page 153: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

16.46. 派生クエリのユニフィケーション

JBoss Rules は、派生クエリのユニフィケーションに対応しています。これは引数はオプションであるという意味です。静的なフィールド org.drools.runtime.rule.Variable.v. を使用して引数を指定せずにJava からクエリを呼び出すことができます (別の変数インスタンスではなく、'v' を使用する必要があります)。これらは 'out' 引数と呼ばれます。

注記注記

クエリ自体は、コンパイル時には引数が in または out のいずれであるかを宣言しません。これは、使うたびにランタイム時にだけ定義することができます。

バグを報告する

or ( Location(z, y;) and isContainedIn(x, z;) )end

rule look when Person( $l : likes ) isContainedIn( $l, 'office'; )then insertLogical( $l 'is in the office' );end

第第16章章 要素と変数要素と変数

149

Page 154: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第17章 ドメイン固有言語 (DSL)

17.1. ドメイン固有言語

ドメイン固有言語 (または DSL) は、問題ドメイン専用のルール言語を作成する手段です。DSL 定義のセットには、DSL 「センテンス」から DRL コンストラクトへの変換が含まれており、基礎となるすべてのルール言語とエンジン機能の使用を可能にします。ルールを DSL ルール (DSLR) ファイルで記述可能で、それが DRL ファイルに変換されます。

DSL and DSLR ファイルはプレーンテキストファイルで、これらのファイルの作成や変更にはどんなテキストエディターでもご利用いただけます。また、DSL の機能が完全に提供されないかもしれませんが、IDE や Web ベースの BRMS で使用できる DSL と DSLR エディターもあります。

バグを報告する

17.2. DSL の使用

DSL は、ドメインオブジェクトやルールエンジンのネイティブ言語やメソッドのモデリングによる技術的な複雑性からルール作成 (およびルール作成者) を切り離す層として機能します。DSL は実装詳細を見せず、ルールロジックの真意にフォーカスします。DSL のセンテンスは、条件要素やルールで繰り返し使用される結果アクションの「テンプレート」としての役割も果たすことができます (バリエーションも少しあり)。このようなバリエーションに対応する手段として提供されるパラメーターを使用して、これらの反復フレーズにマッピングされるように DSL センテンスを定義することができます。

バグを報告する

17.3. DSL の例

表表17.1 DSL の例の例

例例 説明説明

[when] は、式のスコープを示します (ルールのLHS または RHS に有効であるかどうかなど)。

括弧内のキーワードの後にくる部分は、ルールで使用する式です。

等号 = の右部分で、式がルール言語にマッピングされています。この文字列の形式はそのマッピング先にによって異なります (RHS または LHS)。LHS の場合は、通常の LHS 構文に基づいた用語でなければならず、RHS の場合は、Java ステートメントの場合があります。

バグを報告する

17.4. DSL パーサーの仕組み

DSL パーサーが DSL で記述されたルールファイルの行と DSL 定義の式を照合するときは、必ず文字列操作の 3 つの手順が実行されます。

DSL は、式に括弧で囲まれた変数名が含まれる場所に表示される文字列の値を抽出します。

[when]Something is {colour}=Something(colour=="{colour}")

JBoss Rules 5 リファレンスガイドリファレンスガイド

150

Page 155: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

このようなキャプチャーで取得した値は、その名前がマッピングの右辺部 (RHS) に出てくる箇所で常に補間されます。

補間された文字列は、DSL ルールファイルの行の式全体と照合して合致したものを置き換えます。

注記注記

例えば、前にくる文字を任意とする'?' を使用することができます。これを使用するリユは、DSL の自然言語の句にあるバリエーションに対応するためです。しかし、これらの式が正規表現のパターンだとすると、Java のパターン構文のワイルドカード文字はすべて、バックスラッシュ ('\') が前にきた場合エスケープされなければなりません。

バグを報告する

17.5. DSL コンパイラー

DSL コンパイラーは DSL ルールファイルを行ごとに変換します。変換する必要がない場合は、キャプチャーが文字テキスト (単語または単一文字) で囲まれてることを確認してください。結果、パーサーが行う照合オペレーションは、行の中からサブストリングを抽出します。以下の例は、引用句が特有な文字として使用されています (キャプチャーを囲む文字は補間の際には含まれず内容だけが含まれます)。

バグを報告する

17.6. DSL 構文の例

表表17.2 DSL 構文の例構文の例

名前名前 説明説明 例例

引用符 ルールエディターにより入力される可能性のあるテキストデータに対して引用符を使用します。テキストが正しく照合されるように取得された値を単語で囲むこともできます。

括弧 DSL マッピングでは、括弧 "{" と"}" 変数の定義または参照を囲むためだけに使用する必要があります。括弧で囲むとキャプチャーとなります。表現または右辺部で置き換えたテキストがリテラルで処理される必要がある場合、これらを、表現または右辺部の置換テキスト内でリテラルに使用する場合は、バックスラッシュ ("\") を前に付けてエスケープする必要があります。

[when]something is "{color}"=Something(color=="{color}")[when]another {state} thing=OtherThing(state=="{state}"

[then]do something= if (foo) \{ doSomething(); \}

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)

151

Page 156: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

正しい構文でマッピングする例 なし

DSL 展開例 なし

名前名前 説明説明 例例

注記注記

DSL ルール行からプレーンテキストをキャプチャーし、式で文字列リテラルとして使用する場合は、マッピングの右辺部で引用符を提供する必要があります。

# This is a comment to be ignored.[when]There is a person with name of "{name}"=Person(name=="{name}")[when]Person is at least {age} years old and lives in "{location}"= Person(age >= {age}, location=="{location}")[then]Log "{message}"=System.out.println("{message}");[when]And = and

There is a person with name of "Kitty" ==> Person(name="Kitty")Person is at least 42 years old and lives in "Atlanta" ==> Person(age >= 42, location="Atlanta")Log "boo" ==> System.out.println("boo");There is a person with name of "Bob" and Person is at least 30 years old and lives in "Utah" ==> Person(name="Bob") and Person(age >= 30, location="Utah")

JBoss Rules 5 リファレンスガイドリファレンスガイド

152

Page 157: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

17.7. DSL 表現の連鎖

DSL 表現は、一度に使用できるように一つに連鎖させることができます。終了箇所と開始箇所、パラメーターを表すテキストの終了箇所を明確にする必要があります (パラメーター値として行末まですべてのテキストが取得されてしまう危険性があります)。DSL 定義ファイルの順番に従い、DSL 表現が次々に試行されます。合致があると、残りの DSL 表現も検証されます。

バグを報告する

17.8. ファクトへの制約の追加

表表17.3 ファクトへの制約の追加ファクトへの制約の追加

名前名前 説明説明 例例

LHS 条件の表現 DSL の機能は、単純な規定により制約をパターンに追加することができます。DSL 表現がハイフン("-") で開始されている 場合、フィールド制約と考えられるため、その前にくる最後のパターンの行に追加されます。

この例では、クラス Cheese には type、price、age、country のフィールドがあります。通常のDRL で LHS の条件を表現することができるものもあります。

DSL の定義 この例にある DSL 定義は、3 つのDSL 句となり、これらのフィールドに関する制約の組み合わせを作成する際に使用することができます。

Cheese(age < 5, price == 20, type=="stilton", country=="ch")

[when]There is a Cheese with=Cheese()[when]- age is less than {age}=age<{age}[when]- type is '{type}'=type=='{type}'[when]- country equal to '{country}'=country=='{country}'

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)

153

Page 158: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

"-" パーサーは、"-" で始まる行を取得し、先行のパターンに制約として追加します (必要に応じてコンマを挿入します)。

DSL 句の定義 フィールド制約を処理する様々な演算子や一般的な表現に対してDSL 句を定義すると、DSL のエントリ数を減らします。

[when][]- {field:\w*} {operator}{value:\d*}={field} {operator}{value}

名前名前 説明説明 例例

There is a Cheese with - age is less than 42 - type is 'stilton'

Cheese(age<42, type=='stilton')

[when][]is less than or equal to=<=[when][]is less than=<[when][]is greater than or equal to=>=[when][]is greater than=>[when][]is equal to===[when][]equals===[when][]There is a Cheese with=Cheese()

JBoss Rules 5 リファレンスガイドリファレンスガイド

154

Page 159: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

DSL 定義ルール なし

この特定の場合では、"is lessthan" の句は < で置き換えられ、その行は最終の DSL エントリと合致します。これによりハイフンは削除されますが、最終結果は先行のパターンに制約として追加されます。すべての行を処理した後の結果 DRL テキストは以下のようになります。

名前名前 説明説明 例例

注記注記

個別の DSL 式が同じ行を順番に照合する場合は、DSL のエントリの順序が重要です。

バグを報告する

17.9. DSL 開発のヒント

お使いのアプリケーションが必要とするルールの表現サンプルを記述して、開発しながらテストも行います。

DRL と DSLR のルールは、データモデルにしたがってエンティティを参照します。このデータモデルは、ルール内で定義される推測プロセスにより変化するアプリケーションデータを表現します。

データモデルの方が多くがファクトの場合、ルールの記述はより簡単です。

変数部分をパラメーターとしてマークします。こうすることで、便利な DSL エントリに関する信頼できる糸口が提供されます。

特定の条件要素やアクションを大なり記号 (">") を行頭につけ DRL 形式で残すことで、この初期設計段階で条件やアクション関連の実装決定を延期することができます。

新しいルールは、既存の DSL 定義を再利用したり、パラメータを既存の条件または結果エントリに追加したりすることにより記述できます。

DSL エントリの数は少なくして抑えてください。パラメーターを使用すると、類似のルールパターンまたは制約に対して、同じ DSL センテンスを適用できます。

There is a Cheese with - age is less than 42 - rating is greater than 50 - type equals 'stilton'

Cheese(age<42, rating > 50, type=='stilton')

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)

155

Page 160: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

17.10. DSL および DSLR 参照

DSL ファイルは行指向形式のテキストファイルです。このエントリは、DRL 構文にしたがい、DSLRファイルをファイルに変換するために使用されます。

"#" または "//" (前にスペースの有無に拘らず) で始まる行は、コメントとして扱われます。"#/" で始まるコメント行は、デバッグオプションを要求する単語がないかスキャンされます。以下を参照してください。

開始括弧 ("[") で始まる行は、DSL エントリ定義の最初の行とみなされます。

他の任意の行は先行する DSL エントリ定義に追加され、行の最後はスペースで置換されます。

バグを報告する

17.11. DSL エントリの構成

DSL エントリは、以下の 4 つの部分から構成されます。

スコープの定義。括弧 ("[" および "]") で囲まれた "when" または"condition"、"then" または"consequence"、"*"、"keyword" の 1 つで記述されています。これは、DSL エントリがルールの条件や結果 (あるいは条件と結果両方) に対して有効であるかを指定します。"keyword" のスコープは、エントリがグローバルかどうか (DSLR ファイル内のどこでも認識されるか) を指定します。

型の定義。Java クラス名として記述し括弧で括ります。この部分は、次の部分が開始括弧で始まらない限りオプションです。括弧内が空白のペアは無効です。

正規表現 (Java) で構成され、任意の数の組み込み変数定義変数定義を持ち等号 ("=") で終わる DSL 式。変数定義は波括弧 ("{" と "}") で囲まれ、変数名と 2 つのオプションの添付 (コロン (":") で区切られます) から構成されます。添付が 1 つの場合は、一致するテキストの正規表現が変数に割り当てられます。添付が 2 つの場合は、最初の添付が GUI エディターのヒントとなり、2 つ目の添付が正規表現になります。

表現内で文字をリテラルで使用する必要がある場合、正規表現で "magic" 状態文字はすべて、その文字の前にバックスラッシュ ("\") を付けてエスケープする必要があることに注意してください。

行の区切り等号後の部分は、正規表現に一致する DSLR テキストの置換テキストです。これには変数参照 (波括弧で囲まれた変数名) を含めることができます。オプションで、変数名の後に感嘆符 ("!") と変換機能を指定できます。以下を参照してください。

置き換え文字列でリテラルに括弧 ("{" および "}") を使用する必要がある場合は、これらの括弧の前にバックスラッシュ ("\") を挿入してエスケープする必要があります。

バグを報告する

17.12. DSL 拡張のデバッグオプション

表表17.4 DSL 拡張のデバッグオプション拡張のデバッグオプション

JBoss Rules 5 リファレンスガイドリファレンスガイド

156

Page 161: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

単語単語 説明説明

結果 結果となる DRL テキストを行番号とともに出力します。

steps 条件および結果行の各拡張ステップを出力します。

keyword スコープ "keyword" を持つすべての DSL エントリの内部表現をダンプします。

when スコープ "when" または "*" を持つすべての DSL エントリの内部表現をダンプします。

then スコープ "when" または "*" を持つすべての DSL エントリの内部表現をダンプします。

usage すべての DSL エントリの使用統計を表示します。

バグを報告する

17.13. DSL 定義の例

以下は、DSL 定義の例です。

バグを報告する

17.14. DSLR ファイルの変換

DSLR ファイルの変換は以下のように行われます。

1. テキストがメモリに読み込まれます。

2. 各 keyword エントリがテキスト全体に適用されます。キーワード定義からの正規表現を変更するには、ホワイトスペースのシーケンスを任意の数のホワイトスペースに一致するパターンで置き換え、変数定義を定義またはデフォルトの (".*?) で提供された正規表現からのキャプチャーで置き換えます。次に、変更された正規表現に一致する文字列がDSLR テキストにない

# Comment: DSL examples

#/ debug: display result and usage

# keyword definition: replaces "regula" by "rule"[keyword][]regula=rule

# conditional element: "T" or "t", "a" or "an", convert matched word[when][][Tt]here is an? {entity:\w+}= ${entity!lc}: {entity!ucfirst} ()

# consequence statement: convert matched word, literal braces[then][]update {entity:\w+}=modify( ${entity!lc} )\{ \}

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)

157

Page 162: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

か徹底的に検索されます。さらに、変数キャプチャーに対応する一致文字列のサブ文字列が抽出され、対応する置換テキストの変数参照が置換され、このテキストによって DSLR テキストの一致文字列が置換されます。

3. 以下で説明されているように、"when" と "then" 間、および "then" と "end" 間の DSLR テキストのセクションは、一律した方法で行ごとに特定され処理されます。

行に対して、行のセクションに関係する各 DSL エントリが、DSL ファイルに現れる順序で取得されます。この正規表現部分は変更されます。ホワイトスペースは任意の数のホワイトスペースと合致するパターンで置換されます。正規表現の変数定義は、この正規表現のキャプチャーにより置換されます (デフォルト値は ".*?")。結果となる正規表現が行のすべてまたは部分に一致する場合、一致箇所が適切に変更された置換テキストで置換されます。

置換テキストの変更は、正規表現キャプチャに対応するテキストで変数参照を置換することによって行われます。このテキストは、変数参照で提供される文字列変換機能に従って変更できます。詳細については以下を参照してください。

同じエントリで定義されない変数を指定する変数参照が存在する場合は、エキスパンダーがその名前の変数にバインドされた値を置換します (これが現在のルールの先行する行のいずれかで定義された場合)。

4. 条件の DSLR 行がハイフンで始まる場合、展開された結果は最後の行に挿入されます。これには (型名の後に括弧のペアがくる) パターンの条件要素を含める必要があります。このペアが空白の場合、展開された行 (有効な制約を含む) が単に挿入されます。それ以外の場合は、コンマ(",") が前に挿入されます。

結果の DSLR 行がハイフンで始まる場合、展開された結果が最後の行に挿入されます。これには、"modify" ステートメントが含まれ、括弧のペア ("{" と "}") で終わります。このペアが空白の場合は、展開された行 (有効なメソッドコールを含む) が単に挿入されます。それ以外の場合は、コンマ (",") が前に挿入されます。

注記注記

現時点では、ハイフンで始まる行を使用して、他の条件要素形式に ("accumulate" など)にテキストを挿入することはできませんできません。または、最初の挿入に対してのみ可能です("eval" など)。

バグを報告する

17.15. 文字列変換関数

表表17.5 文字列変換関数文字列変換関数

名前名前 説明説明

uc すべての文字を大文字に変換します。

lc すべての文字を小文字に変換します。

ucfirst 最初の文字を大文字、他のすべての文字を小文字に変換します。

JBoss Rules 5 リファレンスガイドリファレンスガイド

158

Page 163: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

num 文字列からすべての数字と "-" を抽出します。元の文字列の下二桁の前に "." または "," がある場合、小数点が該当の位置に挿入されます。

a?b/c 文字列を文字列 a と比較し、同じである場合は、bと置換し、同じでない場合は、c と置換します。ただし、c は別の triplet a、b、c である場合があるため、構造全体が実際には変換テーブルになります。

名前名前 説明説明

バグを報告する

17.16. 文字列 DSL 変換関数

表表17.6 文字列文字列 DSL 変換関数変換関数

名前名前 説明説明 例例

.dsl DSL 定義を含むファイルには、通常拡張子 .dsl が与えられます。これは Knowledge Builder に ResourceType.DSL で渡されます。DSL 定義を使用するファイルに対して、拡張子 .dslr を使用する必要があります。Knowledge Builder では ResourceType.DSLR が期待されます。ただし、IDE は、ルールファイルを適切に認識し、使用するためにファイルの拡張子に依存します。

# definitions for conditions[when][]There is an? {entity}=${entity!lc}: {entity!ucfirst}()[when][]- with an? {attr} greater than {amount}={attr} <= {amount!num}[when][]- with a {what} {attr}={attr} {what!positive?>0/negative?%lt;0/zero?==0/ERROR}

第第17章章 ドメイン固有言語ドメイン固有言語 (DSL)

159

Page 164: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

DSL の指定 DSL は、DSL を使用するルールファイルよりも前に KnowledgeBuilder に渡す必要があります。

DSLR ファイルを解析および展開する場合、DSL 設定が読み込まれ、パーサーに提供されます。パーサーは DSL 式を「認識」し、ネイティブのルール言語式に変換します。

名前名前 説明説明 例例

バグを報告する

KnowledgeBuilder kBuilder = new KnowledgeBuilder();Resource dsl = ResourceFactory.newClassPathResource( dslPath, getClass() );kBuilder.add( dsl, ResourceType.DSL );Resource dslr = ResourceFactory.newClassPathResource( dslrPath, getClass() );kBuilder.add( dslr, ResourceType.DSLR );

JBoss Rules 5 リファレンスガイドリファレンスガイド

160

Page 165: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第18章 XML

18.1. XML 形式

警告警告

XML ルール言語は、Drools 5.x で導入された機能に対応するため更新されていませんが、この機能は廃止される可能性があります。

オプションとして、JBoss Rules は、DRL の代わりに "ネイティブ" ルール言語をサポートします。これにより、ユーザーはルールを XML データとして取得および管理できます。非 XML DRL の形式のように、XML 形式はできるだけ早く内部の "AST" 表現に解析されます (SAX パーサーの使用)。外部の変換ステップは必要ありません。

バグを報告する

18.2. XML ルールの例

以下は、XML でルールはどのように記述されるかを示しています。

<?xml version="1.0" encoding="UTF-8"?><package name="com.sample" xmlns="http://drools.org/drools-5.0" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://drools.org/drools-5.0 drools-5.0.xsd"><import name="java.util.HashMap" /><import name="org.drools.*" /><global identifier="x" type="com.sample.X" /><global identifier="yada" type="com.sample.Yada" /><function return-type="void" name="myFunc"><parameter identifier="foo" type="Bar" /><parameter identifier="bada" type="Bing" /><body> System.out.println("hello world"); </body></function><rule name="simple_rule"><rule-attribute name="salience" value="10" /><rule-attribute name="no-loop" value="true" /><rule-attribute name="agenda-group" value="agenda-group" /><rule-attribute name="activation-group" value="activation-group" /><lhs><pattern identifier="foo2" object-type="Bar" ><or-constraint-connective><and-constraint-connective><field-constraint field-name="a"><or-restriction-connective><and-restriction-connective><literal-restriction evaluator=">" value="60" /><literal-restriction evaluator="<" value="70" /></and-restriction-connective><and-restriction-connective><literal-restriction evaluator="<" value="50" /><literal-restriction evaluator=">" value="55" /></and-restriction-connective></or-restriction-connective></field-constraint><field-constraint field-name="a3"><literal-restriction evaluator="==" value="black" /></field-constraint></and-constraint-connective><and-constraint-connective><field-constraint field-name="a"><literal-restriction evaluator="==" value="40" /></field-constraint><field-constraint field-name="a3"><literal-restriction evaluator="==" value="pink" /></field-constraint></and-constraint-connective><and-constraint-connective><field-constraint field-name="a"><literal-restriction evaluator="==" value="12"/></field-constraint><field-

第第18章章 XML

161

Page 166: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

constraint field-name="a3"><or-restriction-connective><literal-restriction evaluator="==" value="yellow"/><literal-restriction evaluator="==" value="blue" /></or-restriction-connective></field-constraint></and-constraint-connective></or-constraint-connective></pattern><not><pattern object-type="Person"><field-constraint field-name="likes"><variable-restriction evaluator="==" identifier="type"/></field-constraint></pattern><exists><pattern object-type="Person"><field-constraint field-name="likes"><variable-restriction evaluator="==" identifier="type"/></field-constraint></pattern></exists></not><or-conditional-element><pattern identifier="foo3" object-type="Bar" ><field-constraint field-name="a"><or-restriction-connective><literal-restriction evaluator="==" value="3" /><literal-restriction evaluator="==" value="4" /></or-restriction-connective></field-constraint><field-constraint field-name="a3"><literal-restriction evaluator="==" value="hello" /></field-constraint><field-constraint field-name="a4"><literal-restriction evaluator="==" value="null" /></field-constraint></pattern><pattern identifier="foo4" object-type="Bar" ><field-binding field-name="a" identifier="a4" /><field-constraint field-name="a"><literal-restriction evaluator="!=" value="4" /><literal-restriction evaluator="!=" value="5" /></field-constraint></pattern></or-conditional-element><pattern identifier="foo5" object-type="Bar" ><field-constraint field-name="b"><or-restriction-connective><return-value-restriction evaluator="==" >a4 + 1</return-value-restriction><variable-restriction evaluator=">" identifier="a4" /><qualified-identifier-restriction evaluator="=="> org.drools.Bar.BAR_ENUM_VALUE </qualified-identifier-restriction></or-restriction-connective></field-constraint></pattern><pattern identifier="foo6" object-type="Bar" ><field-binding field-name="a" identifier="a4" /><field-constraint field-name="b"><literal-restriction evaluator="==" value="6" /></field-constraint></pattern></lhs><rhs> if ( a == b ) { assert( foo3 ); } else { retract( foo4 ); } System.out.println( a4 ); </rhs></rule></package>

JBoss Rules 5 リファレンスガイドリファレンスガイド

162

Page 167: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第第18章章 XML

163

Page 168: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

JBoss Rules 5 リファレンスガイドリファレンスガイド

164

Page 169: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

18.3. XML 要素

表表18.1 XML 要素要素

名前名前 説明説明

global ルールで参照できる Global オブジェクトを定義します。

function 関数をルールで使用できるようにするための関数宣言が含まれます。戻り型、一意の名前、パラメーターをコードスニペットのボディに指定する必要があります。

import ルールで使用する型をインポートします。

バグを報告する

18.4. ルール要素の詳細

このルールの例には LHS および RHS (条件と結果) のセクションがあります。RHS はルールがアクティブ化される際に実行されるセマンティックコードのブロックです。LHS は、条件要素、制約、制限のネスト化された要素が含まれるため、RHS よりも若干複雑です。

<rule name="simple_rule"><rule-attribute name="salience" value="10" /><rule-attribute name="no-loop" value="true" /><rule-attribute name="agenda-group" value="agenda-group" /><rule-attribute name="activation-group" value="activation-group" /><lhs><pattern identifier="cheese" object-type="Cheese"><from><accumulate><pattern object-type="Person"></pattern><init> int total = 0; </init><action> total += $cheese.getPrice(); </action><result> new Integer( total ) ); </result></accumulate></from></pattern><pattern identifier="max" object-type="Number"><from><accumulate><pattern identifier="cheese" object-type="Cheese"></pattern><external-function evaluator="max" expression="$price"/></accumulate></from></pattern></lhs><rhs> list1.add( $cheese );</rhs></rule>

第第18章章 XML

165

Page 170: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

18.5. XML ルールの要素

表表18.2 XML ルールの要素ルールの要素

要素要素 説明説明

パターン 型 (クラス) を指定し、おそらくそのクラスのインスタンスに変数をバインドできるようになります。必要がある制約と制限がパターンオブジェクトの下にネストされます。Predicate および Return Value 制約を使用すると、Java 表現を組み込むことができます。

条件要素 (not、exists、and、or) DRL のように動作します。以下にネストされた要素と "and" 要素は論理的に "and" によって結合されます。"or" (さらにネストできます) と同様に、"Exists"と "Not" はパターンと連携してパターンの制約を満たすファクトが存在するかしないかをチェックします。

Eval ブール値 (単なる断片なのでセミコロンで終了しないでください) と評価される限り、有効な Java コードのスニペットを実行できます。これには、関数の呼び出しを含めることができます。ルールエンジンが毎回評価する必要があるため、Eval は列よりも非効率です。ただし、これは列制約で何をする必要があるか表現できる場合は "catch all" 機能です。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

166

Page 171: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

18.6. XML と DRL 間の自動変換

JBoss Rules には形式間を変換するいくつかのユーティリティクラスが含まれます。これは、ソース形式からのルールを AST に解析し、適切なターゲット形式に「ダンプ」することで動作します。これにより、たとえば、ルールを DRL で記述して XML にエクスポートすることができます。

バグを報告する

18.7. XML と DRL 間の自動変換用のクラス

XML と DRL ファイル感で変換を行う際に使用するクラスを以下に示しています。これらの組み合わせを使用することで、形式間の変換が可能になります (変換がまたに戻すことも可能)。

DrlDumper - DRL のエクスポート

DrlParser - DRL の読み込み

XmlPackageReader - XML の読み込み

注記注記

DSL は (DSL を使用する DRL から) 保護されませんが、変換は可能です。

バグを報告する

第第18章章 XML

167

Page 172: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第19章 JAVA ルールエンジンアプリケーションプログラミングインターフェース

19.1. JSR94

JSR94 は、JBoss Rules で使用されている API です。単一の API から複数のルールエンジンに対応することができます。JSR94 は、ルール言語自体の処理は行いません。

JSR94 規格は、ルールエンジンの機能に関する「最小限の共通点」を表します。つまり、標準の Knowledge API よりも JSR94 には機能が少なくなっています。JSR94 を使用すると、JBoss Rules の機能をすべて使用することができません。global を使用して、JSR94 と連携するプロパティマップでDRL、DSL、XML に対応する必要があります。これにより、移植性のない機能を導入します。

注記注記

JSR94 にはルール言語がないため、ルールエンジンを切り替える際の複雑性は少ししか解決できないに拘らず、利点はほとんどありません。Red Hat は、Knowledge (JBossRules および jBPM) API 以外でプログラミングを行うように推奨しています。

バグを報告する

19.2. JAVAX.RULES インターフェース

Handle

Handle は、StatefulRuleSession に追加された WorkingMemory からオブジェクトから取得しなおすために使用されます。Handle で WorkingMemory から Object を変更または削除することができます。オブジェクトを変更するには、 StatefulRuleSession から updateObject() を呼び出します。オブジェクトを削除するには、Handle で removeObject() をパラメーターとして呼び出します。Java Rule Engine API の実装の内部では、カプセル化された Knowledge (Drools および jBPM) の modifyObject() および retractObject() メソッドを呼び出します。

ObjectFilter

このインターフェースは RuleSession のオブジェクトをフィルタリングするために使用します。

RuleExecutionSetMetadata

RuleExecutionSetMetadata は RuleExecutionSet の名前、説明、URI を格納するために使用します。

RuleRuntime

RuleRuntime は RuleSession へのキーで、RuleRuntime は RuleServiceProvider から取得します。

RuleRuntime を取得する場合、RuleSession を開くために createRuleSession() を呼び出します。

JBoss Rules 5 リファレンスガイドリファレンスガイド

168

Page 173: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

RuleRuntime で RuleAdministrator で登録したすべての RuleExecutionSets の URI 一覧を取得できます。RuleSession をルールエンジンに対して開くためには、文字列としての URI が必要です。ルールエンジンは、RuleSession 内の RuleExecutionSet ルールを使用します。

Map は、Global に使用します。Global は (Drools 2.x では) 以前 ApplicationData と呼ばれていました。キーは Global の識別子である必要があり、値は Global として使用するオブジェクトである必要があります。

RuleSession

RuleSession は、ルールエンジンへ問い合わせする場合に使用するオブジェクトです。

RuleRuntime から RuleSession を取得する場合、StatefulRuleSession か StatelessRuleSessionのいずれかです。

すべてのリソースが解放されるように、release()-メソッドを呼び出します。

StatefulRuleSession

1 回以上ルールエンジンを実行する必要がある場合、StatefulRuleSession を実行します。オブジェクトのアサート、ルールの実行などができます。

Rule Session にアサートするすべてのオブジェクトに関する Handle を取得します。ワーキングメモリのオブジェクトを削除または変更する際に必要になりますので、なくさないようにしてください。実装内で使用される Drools のワーキングメモリには直接問い合わせできません。これには RuleSession を使用します。

StatelessRuleSession

StatelessRuleSession は、ルールエンジンへのコンタクト 1 つのみとなります。ルールエンジンへオブジェクトの一覧を渡して、ルールエンジンはオブジェクトすべてをアサートし直後に実行を開始します。結果はオブジェクトの一覧となります。結果一覧の内容はルールにより左右されmさう。ルールがワーキングメモリーからのオブジェクトを変更または削除しない場合、再度追加したオブジェクトをすべて取得するはずです。

取得前にオブジェクトの結果一覧をフィルタリングする ObjectFilter を使用することができます。

バグを報告する

19.3. JAVAX.RULES クラス

RuleServiceProvider

RuleServiceProvider により、新しいルールセッションを開くために必要な RuleAdministratorや RuleRuntime へアクセスできるようにします。RuleServiceProvider を取得するには、RuleServiceProviderManager.getRuleServiceProvider() を呼び出します。

J2EE 環境では、RuleServiceProvider を JNDI にバインドして、ルックアップを作成してアプリケーションすべてに設置することができます。

RuleServiceProviderManager

RuleServiceProvider は頻繁に DriverManager と比較して JDBC で使用します。これは、データベースのドライバーを設定するように機能します。

バグを報告する

第第19章章 JAVA ルールエンジンアプリケーションプログラミングインターフェースルールエンジンアプリケーションプログラミングインターフェース

169

Page 174: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

19.4. JAVAX.RULES の例外

ConfigurationException

この例外は、ユーザー設定にエラーがあった場合に送出されます。

InvalidHandleException

この例外は、クライアントが無効な Handle をルールエンジンに渡した場合に送出されます。

InvalidRuleSessionException

InvalidRuleSessionException はメソッドが RuleSession で呼び出され、RuleSession の内部のステータスが無効の場合に送出されるはずです。これは、StatefulRuleSession が直列化され外部リソースにアクセスできなうなってしまった場合に発生する場合があります。この例外は、RuleSession は無効のステータスであるとのシグナルを送信する際にも使用されます (releaseメソッドが呼び出された後に使用しようとし場合など)。 (JCP API ドキュメンテーションより抜粋)

RuleException

javax.rules パッケージの例外クラスすべてに対するベースクラス

RuleExecutionException

Drools 3 JSR 94 実装ではこの例外は送出されません。

RuleExecutionSetNotFoundException

この例外は、クライアントが RuleExecutionSet を RuleRuntime から依頼して、URI またはRuleExecutionSet が見つからなかった場合に送出されます (JCP API ドキュメンテーションから抜粋)。

RuleSessionCreateException

この例外は、クライアントが RuleRuntime から RuleSession を依頼して、RuleSession を返すことができないといったエラーが発生した場合に送出されます (JCP API ドキュメンテーションから抜粋)。

RuleSessionTypeUnsupportedException

この例外は、クライアントが RuleSession を依頼してベンダーが指定の型の対応していないか、RuleExecutionSet 自体が依頼したモードに対応していない場合に送出されます (JCP APIドキュメンテーションから抜粋)。

バグを報告する

19.5. ルールサービスプロバイダーの使用

手順手順19.1 タスクタスク

1. 以下のコードを使用して JBoss Rules ルールサービスプロバイダーを読み込みます。

Class ruleServiceProviderClass = Class.forName("org.drools.jsr94.rules.RuleServiceProviderImpl");

JBoss Rules 5 リファレンスガイドリファレンスガイド

170

Page 175: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. 以下のコードを使用して登録します。

RuleServiceProviderManager.registerRuleServiceProvider( "http://jboss.com/products/rules", ruleServiceProviderClass);

3. 以下のコードを使用して RuleServiceProvider への呼び出しを行います。

RuleServiceProviderManager.getRuleServiceProvider("http://jboss.com/products/rules");

4. ルールサービスを停止するには、このコードで登録を解除します。

RuleServiceProviderManager.deregisterRuleServiceProvider( "http://jboss.com/products/rules");

バグを報告する

19.6. JAVAX.RULES.ADMIN インターフェース

LocalRuleExecutionSetProvider

Rule

RuleAdministrator

RuleExecutionSet

RuleExecutionSetProvider

バグを報告する

19.7. JAVAX.RULES.ADMIN の例外

RuleAdministrationException

javax.rules.admin パッケージの administration RuleException クラスすべてに対するベースクラス (JCP API ドキュメンテーションから抜粋)

RuleExecutionSetCreateException

ルール実行セットを作成する際にエラーが発生すると、この例外が起こります。

RuleExecutionSetDeregistrationException

URI からルール実行セットの登録解除を試行するときにエラーが発生すると、この例外が起こります。

RuleExecutionSetRegisterException

URI からルール実行セットに登録を試行するときにエラーが発生すると、この例外が起こります。

バグを報告する

19.8. RULESERVICEPROVIDER

第第19章章 JAVA ルールエンジンアプリケーションプログラミングインターフェースルールエンジンアプリケーションプログラミングインターフェース

171

Page 176: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

RuleServiceProvider により、RuleRuntime や RuleAdministrator API にアクセスできるようになります。RuleAdministrator は、RuleExecutionSet オブジェクトの管理に管理 API を提供することで、RuleExecutionSet の登録が可能でき、RuleRuntime 経由で取得することができるようになります。

バグを報告する

19.9. RULESERVICEPROVIDERMANAGER

RuleServiceProviderManager は、RuleServiceProviders の登録や取得を管理します。JBossRulesRuleServiceProvider 実装は、クラスが Class.forName を使用して読み込まれる際に、JDBC ドライバーとよく似た方法で、自動的に静的ブロックで登録されます。

バグを報告する

19.10. RULESERVICEPROVIDER 自動登録の例

以下は、自動 RuleServiceProvider の登録例です。

バグを報告する

19.11. LOCALRULEEXECUTIONSET を RULEADMINISTRATOR API で登録

手順手順19.2 タスクタスク

1. RuleExecutionSet を作成します。空の LocalRuleExecutionSetProvider またはRuleExecutionSetProvider を返すファクトリメソッドを提供する RuleAdministrator を使用することで、この作成が可能です。

2. RuleExecutionSet の名前を指定します。

3. 以下のように RuleExecutionSet を登録します。

4. LocalRuleExecutionSetProvider を使用して、ストリームなどのような、直列化できないローカルソースから RuleExecutionSets を読み込みます。

5. RuleExecutionSetProvider を使用して、DOM 要素やパッケージなどのような、直列化できるソースから RuleExecutionSets を読み込みます。"ruleAdministrator.getLocalRuleExecutionSetProvider( null );" と the"ruleAdministrator.getRuleExecutionSetProvider( null );" (null をパラメーターとして使用)

// RuleServiceProviderImpl is registered to "http://drools.org/"// via a static initialization blockClass.forName("org.drools.jsr94.rules.RuleServiceProviderImpl");

// Get the rule service provider from the provider manager.RuleServiceProvider ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider("http://drools.org/");

// Register the RuleExecutionSet with the RuleAdministratorString uri = ruleExecutionSet.getName();ruleAdministrator.registerRuleExecutionSet(uri, ruleExecutionSet, null);

JBoss Rules 5 リファレンスガイドリファレンスガイド

172

Page 177: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

6. 以下の例は、LocalRuleExecutionSet の登録の方法の例を示しています。

7. "ruleExecutionSetProvider.createRuleExecutionSet( reader, null )" プロパティを使用して、受信ソースの設定を提供します。null が指定されると、デフォルトを使用して drl として入力を読み込みます。マップで利用可能なキーは "source" と "dsl" です。"source" キーは、値として"drl" か "xml" を取ります。

8. "source" を "drl" に設定して DRL を読み込み、"xml" を設定して XML ソースを読み込みます。"xml" は "dsl" key/value 設定を無視します。"dsl" キーは、Reader または String (dsl のコンテンツ) を値として取ることができます。以下の dsl の例を参照してください。

バグを報告する

19.12. ステートフルおよびステートレス RULESESSIONS

手順手順19.3 タスクタスク

// Get the RuleAdministrationRuleAdministrator ruleAdministrator = ruleServiceProvider.getRuleAdministrator();LocalRuleExecutionSetProvider ruleExecutionSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider( null );

// Create a Reader for the drlURL drlUrl = new URL("http://mydomain.org/sources/myrules.drl");Reader drlReader = new InputStreamReader( drlUrl.openStream() );

// Create the RuleExecutionSet for the drlRuleExecutionSet ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet( drlReader, null );

// Get the RuleAdministrationRuleAdministration ruleAdministrator = ruleServiceProvider.getRuleAdministrator();LocalRuleExecutionSetProvider ruleExecutionSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider( null );

// Create a Reader for the drlURL drlUrl = new URL("http://mydomain.org/sources/myrules.drl");Reader drlReader = new InputStreamReader( drlUrl.openStream() );

// Create a Reader for the dsl and a put in the properties mapURL dslUrl = new URL("http://mydomain.org/sources/myrules.dsl");Reader dslReader = new InputStreamReader( dslUrl.openStream() );Map properties = new HashMap();properties.put( "source", "drl" );properties.put( "dsl", dslReader );

// Create the RuleExecutionSet for the drl and dslRuleExecutionSet ruleExecutionSet = ruleExecutionSetProvider.createRuleExecutionSet( reader, properties );

第第19章章 JAVA ルールエンジンアプリケーションプログラミングインターフェースルールエンジンアプリケーションプログラミングインターフェース

173

Page 178: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

1. 以下のように RuleServiceProvider へアクセスしてランタイムを取得します。

2. ルールセッションを作成するには、RuleRuntime パブリック定数 2 つの内 1 つを使用します。パブリック定数は、"RuleRuntime.STATEFUL_SESSION_TYPE" と"RuleRuntime.STATELESS_SESSION_TYPE" で RuleSession をインスタンス化するRuleExecutionSet に URI を追加します。

3. オプションで、Global を指定するプロパティにアクセスします。

4. createRuleSession(...) メソッドは、RuleSession インスタンスを返します。StatefulRuleSession または StatelessRuleSession にキャストする必要があります。

5. StatelessRuleSession を使用すると、オプションのフィルター、オブジェクト一覧を渡すexecuteRules(List list) を呼び出し、結果のオブジェクトが返されます。

バグを報告する

19.13. JSR94 での GLOBAL の使用

JSR94 は、RuleSession ファクトリメソッドに渡されるプロパティマップを使用することで global に対応しています (移植性がない形で)。Global は DRL または XML ファイルで先に定義する必要があります。そうでないと、例外が送出されます。キーは、DRL または XML で宣言された識別子を表現し、値は実行時に使用するインスタンスとなります。

バグを報告する

19.14. JSR94 で GLOBAL を使用した例

以下は、JSR94 での global の実装例です。

RuleRuntime ruleRuntime = ruleServiceProvider.getRuleRuntime();

(StatefulRuleSession) session = ruleRuntime.createRuleSession( uri, null, RuleRuntime.STATEFUL_SESSION_TYPE );session.addObject( new PurchaseOrder( "cheese" ) );session.executeRules();

(StatelessRuleSession) session = ruleRuntime.createRuleSession( uri, null, RuleRuntime.STATELESS_SESSION_TYPE );List list = new ArrayList();list.add( new PurchaseOrder( "even more cheese" ) );

List results = new ArrayList();results = session.executeRules( list );

java.util.List globalList = new java.util.ArrayList( );java.util.Map map = new java.util.HashMap( );

JBoss Rules 5 リファレンスガイドリファレンスガイド

174

Page 179: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

DRL で global "一覧"を宣言するのを忘れないでください。

バグを報告する

19.15. JSR94 に関する参考資料

JSR94 に関する詳細情報は、以下のリンクを参照してください。

1. Java Rule Engine API (JSR 94) の公式な JCP 仕様

http://www.jcp.org/en/jsr/detail?id=94

2. Java Rule Engine API ドキュメンテーション

http://www.javarules.org/api_doc/api/index.html

3. The Logic From The Bottom Line: An Introduction to The Drools Project. N. Alex Rupp 著 (2004年に TheServiceSide.com で公開)

http://www.theserverside.com/articles/article.tss?l=Drools

4. Getting Started With the Java Rule Engine API (JSR 94): Toward Rule-Based Applications. Dr.Qusay H. Mahmoud 著 (2005 年 Sun Developer Network で公開)

http://java.sun.com/developer/technicalArticles/J2SE/JavaRule.html

5. Jess and the javax.rules API. Ernest Friedman-Hill 著 (2003 年に TheServerSide.com で公開)

map.put( "list", globalList ); //Open a stateless SessionStatelessRuleSession srs = (StatelessRuleSession) runtime.createRuleSession( "SistersRules", map, RuleRuntime.STATELESS_SESSION_TYPE );...// Persons added to List// call executeRules( ) giving a List of Objects as parameter// There are rules which will put Objects in the List// fetch the list from the mapList list = (java.util.List) map.get("list");

package SistersRules; import org.drools.jsr94.rules.Person; global java.util.List listrule FindSisters when $person1 : Person ( $name1:name ) $person2 : Person ( $name2:name ) eval( $person1.hasSister($person2) ) then list.add($person1.getName() + " and " + $person2.getName() +" are sisters"); assert( $person1.getName() + " and " + $person2.getName() +" are sisters"); end

第第19章章 JAVA ルールエンジンアプリケーションプログラミングインターフェースルールエンジンアプリケーションプログラミングインターフェース

175

Page 181: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第20章 JBOSS DEVELOPER STUDIO

20.1. ルールの統合開発環境 (IDE)

統合開発環境 (IDE) は、様々な形式でルールを編集、テストする環境を提供してアプリケーションと統合します。

JBoss Rules IDE は、Eclpse プラグインとして提供され、Eclipse 内からルールを作成、管理して、お使いのアプリケーションとルールを統合することができます。これはオプションのツールです。JBossRules IDE は Red Hat Developer Studio (以前の JBoss IDE) の一部でもあります。

バグを報告する

20.2. RULES IDE 機能

Rules IDE には以下の機能が含まれています。

1. テキスト/グラフィカルルールエディター

1. DRL 構文を認識して、コンテンツアシストを提供するエディター (アウトラインビューを含む)

2. DSL (ドメイン固有言語) の拡張を認識して、コンテンツアシストを提供するエディター

2. RuleFlow グラフィカルエディター

プロセス (ルールフロー) を表す画像グラフを編集できます。その後、RuleFlow がお使いのルールパッケージに適用され命令形制御を行います。

3. 以下を素早く作成するウィザード

1. "rules" プロジェクト

2. ルールのリソース (DRL ファイル)

3. ドメイン固有言語

4. 決定表

5. ruleflow

4. ドメイン固有言語エディター

1. ユーザーの言語からルール言語へのマッピングを作成して管理します。

5. ルールのバリデーション

1. ルールが入力されると、ルールは背景に構築され可能な場合は問題ビューでエラーが報告されます。

バグを報告する

20.3. JBOSS RULES ランタイム

JBoss Rules ランタイムは、JBoss Rules プロジェクト jars の固有リリース 1 つを表現する jar ファイ

第第20章章 JBOSS DEVELOPER STUDIO

177

Page 182: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルの集まりです。ランタイムを作成するには、希望のリリースに IDE をポイントする必要があります。また、プラグイン自体に含まれる最新の JBoss Rules プロジェクト jar に基づき新しいランタイムを作成することもできます。Eclipse ワークスペースに対してデフォルトの JBoss Rules ランタイムを指定する必要がありますが、個々のプロジェクトはデフォルトを上書きし、そのプロジェクトに対してのみ適切なランタイムを選択できます。

バグを報告する

20.4. JBOSS RULES ランタイムの定義

手順手順20.1 タスクタスク

1. JBoss Rules で新しいセッションを作成します。

2. WindowPreferences を選択します。"Preferences" ダイアログが表示されます。

3. このダイアログの左側の JBoss Rules カテゴリーで、"Installed JBoss Rules runtimes" を選択します。右側のパネルに、現在定義されている JBoss Rules ランタイムが表示されるはずです。

4. add ボタンをクリックします。ダイアログが表示され、ランタイムの名前とランタイムがあるファイルシステムの場所を入力するように求められます。

5. JBoss Rules Eclipse プラグインからデフォルトの jar ファイルを使用するには、Create a newDrools 5 runtime ... ボタンをクリックすると新しい JBoss Rules ランタイムが自動的に作成されます。ファイルブラウザーが表示され、このランタイムを作成するファイルシステムの場所の入力が求められます。その後、プラグインが自動的に必要とされる依存関係を指定のフォルダーにコピーします。

6. JBoss Rules プロジェクトの固有のリリースを 1 つ使用するには、必要とされる JBoss Rulesライブラリと依存パッケージが含まれているファイルシステム上にフォルダーを作成します。ランタイムに名前を指定して、必要な jar がすべて含まれているこのフォルダーの場所を選択します。OK をクリックします。

7. ランタイムは、インストールした JBoss Rules ランタイムのテーブルに表示されます。新しく作成されたランタイムのチェックボックスをクリックして、デフォルトの JBoss Rules ランタイムに設定します。デフォルトの JBoss Rules ランタイムは、プロジェクト固有のランタイムが選択されていない JBoss Rules プロジェクトすべてのランタイムとして使用されます。

8. デフォルトのランタイムを変更し、デフォルトのランタイムを使用しているすべてのプロジェクトがクラスパスを適切に更新するには、Eclipse を再起動します。

バグを報告する

20.5. JBOSS RULES プロジェクトに対するランタイムの選択

手順手順20.2 タスクタスク

1. New JBoss Rules Project ウィザードを使用して、新しい JBoss Rules プロジェクトを作成します。

2. または、Java オブジェクトを右クリックして Convert to JBoss Rules Project ダイアログをクリックすることで、アクションを使用して既存の Java プロジェクトを JBoss Rulesプロジェクトに変換します。プラグインは、必要な jar すべてをプロジェクトのクラスパスに自動的に追加します。

JBoss Rules 5 リファレンスガイドリファレンスガイド

178

Page 183: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

3. オプションで、New JBoss Rules Project ウィザードの最後のページで、プロジェクト固有のランタイムを選択することができます。Use default JBoss Rules runtime チェックボックスのチェックを外して、ドロップダウンボックスで適切なランタイムを選択します。

4. preferences にアクセスして、ランタイムを追加するには、workspace preferences へ移動して、Configure workspace settings ... をクリックします。

5. プロジェクトプロパティを開いて JBoss Rules カテゴリを選択することで、いつでも JBossRules プロジェクトのランタイムを変更することができます。Enable project specific settings チェックボックスにチェックをつけて、ドロップダウンボックスから適切なランタイムを選択します。

6. Configure workspace settings ... リンクをクリックします。すると、現在インストールされているランタイムが表示されている workspace preferences が表示されます。メニューを使用してこのスペースで新しいランタイムを追加します。Enable project specific settings チェックボックスの選択を解除すると、global preferences で定義されているデフォルトのランタイムを使用します。

バグを報告する

20.6. RULE ファイルの例

新しく作成されたプロジェクトには、src/rules ディレクトリの中にあるサンプルのルールファイル(Sample.drl)、JBoss Rules エンジンでルールを実行するために使用できるサンプルの Java ファイル(DroolsTest.java) が含まれています。これは、com.sample パッケージの src/java フォルダーに入っています。実行時に必要なその他の jar は、JBoss Rules Library と呼ばれる、カスタムのクラスパスコンテナーのクラスパスに追加されます。

バグを報告する

20.7. JBOSS RULES BUILDER

JBoss Rules プラグインは JBoss Rules Builder 機能を Eclipse インスタンスに追加します。つまり、リソースが変更されるとルールを構築してバリデーションを行うプロジェクトでビルダーを有効にすることができます。これは、Rule Project ウィザードで自動的に有効になりますが、プロジェクト上で手動で有効にすることも可能です。ルールを完全にバリデーションするには、当然ながら単体テストでルールを実行する必要があります。

注記注記

ファイルに 500 以上のルールが含まれるルールファイルの場合、パフォーマンスが低下する可能性があります。対処するには、ビルダーをオフにするか、ルールエディターをまだ使用できる .rule ファイルに大きいルールを設定してください。ただし、バックグラウンドでルールの構築は行われません。

バグを報告する

20.8. 新規ルールの作成

手順手順20.3 タスクタスク

1. 空の .drl テキストファイルを作成します。

第第20章章 JBOSS DEVELOPER STUDIO

179

Page 184: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. このファイルにルールをコピーして貼り付けます。

3. 保存して終了します。

4. または、Rules ウィザードを使用してルールを作成します。この際、Ctrl+N を渡すか、ツールバーから選択します。

5. このウィザードは、ルールリソースを生成するための基本オプションに関する入力を求めます。ルールファイルを保存するには、ディレクトリ src/rules を通常作成して、適切な名前のサブディレクトリを作成します。パッケージ名は必須で、Java のパッケージ名とよく似ています (つまり、関連のルールをグループ化するための名前空間を設定します)。

6. 適切なオプションを選択して、Finish をクリックします。

結果結果

展開可能なルールスケルトンが完成しました。

バグを報告する

20.9. ルールエディター

ルールエディターは、ルールマネージャーおよび開発者が変更を加えるところです。ルールエディターは、Eclipse の通常のテキストエディターのパターンに従います。このルールエディターは、ポップアップコンテンツアシストがあり、Ctrl+Space を押すとポップアップコンテンツアシストが起動します。

ルールエディターは、.drl (または .rule) の拡張子を持つファイル上で動作します。通常、これらには関連のルールが含まれていますが、同じパッケージの名前空間に入れることでグループ化されている個別ファイルにルールを入れることも可能です。これらの DRL ファイルはプレーンテキストファイルです。

バグを報告する

20.10. JBOSS ルールビュー

ルールの変更時は、以下のビューを切り替えることができます。

ワーキングメモリのビューワーキングメモリのビュー

JBoss Rules ワーキングメモリの全要素を表示します。

アジェンダのビューアジェンダのビュー

アジェンダにあるすべての要素を表示します。アジェンダにあるルールごとに、ルール名およびバインド変数が表示されます。

グローバルデータのビューグローバルデータのビュー

JBoss Rules ワーキングメモリで現在定義されているすべてのグローバルデータを表示します。

監査ビュー監査ビュー

ルールエンジンの実行時にロギングされたイベントを含む監査ログをツリー形式で表示する際に利用できます。

Rete ビュービュー

JBoss Rules 5 リファレンスガイドリファレンスガイド

180

Page 185: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

DRL ファイルの現在の Rete Network を表示します。DRL エディターウィンドウの下にある "ReteTree" タブをクリックすると表示されます。Rete Network が表示されると、個別のノードでドラッグアンドドロップを使用して、最適なネットワーク全体図をアレンジすることができます。また、長方形をドラッグして複数のノードを選択することもでき、全グループを移動することが可能です。

注記注記

Rete ビューは、JBoss Rules Builder がプロジェクトのプロパティに設定されているプロジェクトでのみ機能します。他のプロジェクトは、回避策をお使いください。現在のプロジェクトの横に JBoss Rules プロジェクトを設定し、Rete ビューで確認するライブラリと DRL を変換します。DRL エディターの右下のタブをクリックしてから、"Generate Rete View" をクリックします。

バグを報告する

20.11. JBOSS RULES ビューの使用

手順手順20.4 タスクタスク

1. JBoss Rules ビューを使用するには、ワーキングメモリを呼び出してコードのブレークポイントを作成します。例えば、workingMemory.fireAllRules() を呼び出す行は、ブレークを設定するには理想的な場所です。

2. デバッガーがジョイント部分で停止した場合、デバッグ変数のビューでワーキングメモリの変数を選択します。次に、利用可能なビューを使用して、選択したワーキングメモリの詳細を表示します。

バグを報告する

20.12. SHOW LOGICAL STRUCTURE

Show Logical Structure は、JBoss Rules ビューで使用します。ワーキングメモリやアジェンダアイテムにある要素の論理構造の表示を切り替えることができます。例えば、論理構造により、要素のセットがより明確にわかるように表示できます。

バグを報告する

20.13. 監査ログの作成

手順手順20.5 タスクタスク

1. 監査ログを作成するには、ルールエンジンを実行します。新しい監査ログを作成するかの選択を求められます。

2. 以下のコードを入力します。

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();// Create a new Knowledge Runtime Logger, that logs to file.// An event.log file is created in the subdirectory log dir (which must exist) of the working directory

第第20章章 JBOSS DEVELOPER STUDIO

181

Page 186: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

3. 監査ビューの最初のアイコン Open Log アクションをクリックしてログを開き、ファイルを選択します。監査ビューには、ルール実行時にロギングされたイベントすべてが表示されます。

バグを報告する

20.14. 監査ビューのイベントアイコン

表表20.1 監査ビューのイベントアイコン監査ビューのイベントアイコン

アイコンアイコン 説明説明

緑色の四角 オブジェクトが挿入されました。

黄色の四角 オブジェクトが更新されました。

赤色の四角 オブジェクトが削除されました。

右向きの矢印 アクティベーションが作成されました。

左向きの矢印 アクティベーションがキャンセルされました。

青色の菱形 アクティベーションが実行されました。

プロセスのアイコン ルールフローが開始または終了しました。

アクティビティアイコン Ruleflow-group のアクティベーションおよびアクティベーション解除

JBoss Rules アイコン ルールまたはルールパッケージが追加または削除されました。

バグを報告する

20.15. 原因取得のメソッド

アクティベーションの実行時にイベントが発生した場合、そのアクティベーションの実行イベントの子として表示されます。以下のイベントが発生すると、原因を取得することができます。

1. イベントを変更または削除するオブジェクトの原因がそのオブジェクトの最後のオブジェクトイベントの場合。オブジェクトがアサートしたイベントまたはそのオブジェクトで最後に変更されたオブジェクトのイベントのいずれかです。

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger( ksession, "log/event");

ksession.insert(...);ksession.fireAllRules();

// stop logginglogger.close();

JBoss Rules 5 リファレンスガイドリファレンスガイド

182

Page 187: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

2. アクティベーションがキャンセルまたは実行されたイベントの原因が該当のアクティベーションの作成イベントの場合。

注記注記

イベントを選択する場合、原因が監査ビューに緑色で表示されます。アクションを右クリックして、"Show Cause" のメニューアイテムを選択します。すると、選択したイベントの原因までスクロールされます。

バグを報告する

20.16. DSL エディター

DSL エディターは、Language (言語) の Rule Expression (ルール表現) へのマッピングをテーブル形式で確認できます。Language Expression (言語表現) は、DSL 設定からの Language Expression を提案できるように、ルールエディターのコンテンツアシストをフィードします (ルールリソースを編集するために読み込むと、ルールエディターは DSL 設定を読み込みます)。

バグを報告する

20.17. ルール言語マッピング

ルール言語のマッピングは、言語表現がルールエンジンコンパイラーによってどのようにコンパイルされるかを定義します。このルールの言語表現の形式は、ルールの条件部分またはアクション部分になるかにより左右されます (例えば、RHS では Java のスニペットの可能性があります)。scope アイテムは、表現が所属するところを指定して、when アイテムは LHS その後に RHS を指定します。さらに *アイテムはどこでも対応できます。また、キーワードのエイリアスを作成することも可能です。

バグを報告する

20.18. ルール言語マッピングでの作業

手順手順20.6 タスクタスク

1. DSL エディターを開きマッピングタブを選択します。

2. マッピングアイテム (表の中の 1 行) を選択して、表の下のテキストフィールドの表現とマッピングを確認します。

3. 編集ボタンをクリックまたは押して編集ダイアログを開きます。

4. その他のボタンでマッピングの削除や追加が可能です。使用中にマッピングを削除しないようにしてください。

バグを報告する

20.19. DSL 変換コンポーネント

表表20.2 DSL 変換コンポーネント変換コンポーネント

第第20章章 JBOSS DEVELOPER STUDIO

183

Page 188: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

名前名前 説明説明

パーサー パーサーは、DSL のルールテキストを行毎に読み込み、言語表現の一部と照合します。照合の後、波括弧 (例: {age}) に囲まれるプレースホルダーに該当する値がルールソースから抽出されます。

プレースホルダー 該当のルール表現のプレースホルダーは、該当する値で置き換えられます。例えば、自然言語表現は、フィールド age および location を元に型 person のファクトに対して 2 つの制約をマッピングします。そして、{age} と {location} の値は、元のルールテキストから抽出されます。

注記注記

drl で特定のルールで言語マッピングを使用しない場合、表現の前に > を付けると、コンパイラーは言語定義にしたがった変換は実施しません。また、ドメイン固有言語はオプションである点にも注意してください。ルールがコンパイルされると、.dsl ファイルも使用できるようにする必要があります。

バグを報告する

20.20. 大きな DRL ファイルで作業する際のヒント

1. 使用する JDK により、Permanent Generation (Perm Gen) の最大サイズを増やすことができます。この方法は、-XX:MaxPermSize=###m で Eclipse を起動します。

2. 4000 以上のルールセットは、Permanent Generation を 128Mb 以上に設定する必要があります。

3. .rule 拡張子を持つファイルにルールを設定します。バックグラウンドのビルダーは、IDE がより早く実行できるように変更が加えられても毎回コンパイルを試行するわけではありません。

バグを報告する

20.21. ブレークポイントの作成

手順手順20.7 タスクタスク

1. ブレークポイントを作成してルールのデバッグをより簡単に行うには、DRL エディターを開き、使用する DRL ファイルを読み込みます。

2. ブレークポイントを追加する行で DRL エディターのルーラーをダブルクリックします。ルールのブレークポイントは、ルールの結果でのみ作成される点に注目してください。ブレークポイントが作成できない行でダブルクリックしても何もおこりません。ブレークポイントは、ルーラーをもう一度ダブルクリックして削除することができます。

3. ルーラーを右クリックします。Toggle breakpoint アクションを含むポップアップメニューが表示されます。ルールのブレークポイントは、ルールの結果でのみ作成することができる点に注意してください。ルールのブレークポイントがその行で作成できない場合は、この

JBoss Rules 5 リファレンスガイドリファレンスガイド

184

Page 189: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

アクションは自動的に無効になります。

4. アクションをクリックして、選択した行にブレークポイントを追加します (ブレークポイントがすでにある場合は削除されます)。

注記注記

Debug Perspective にはブレークポイントのビューが含まれており、定義されたすべてのブレークポイントの参照、そのプロパティの取得、ブレークポイントの有効化/無効化または削除などを行うために、このビューを使用します。

バグを報告する

20.22. JBOSS RULES アプリケーションとしてのデバッグ

手順手順20.8 タスクタスク

1. DRL エディターを開きます。

2. アプリケーションの主要クラスを選択します。

3. 主要クラスの右クリックして、Debug As > サブメニューを選択後、JBoss Rules Application を選びます。

または、Debug ... メニューアイテムを選択して、デバッグ設定の作成、管理、実行を行う新しいダイアログを開きます。

4. 左側のツリーの Drools Application アイテムを選択して、New launch configuration ボタン (ツリーの上にあるツールバーの一番左端のアイコン) をクリックします。これにより新しい設定が作成されますが、最初に選択した主要クラスをもとにすでに入力されているプロパティもあります。

5. デバッグ設定の名前を意味があるものに変更します。他のプロパティについてはすべてデフォルトで確定します。

6. 下側の Debug ボタンをクリックしてアプリケーションのデバッグを開始します。デバッグ設定の定義は一度だけで結構です。JBoss Rules アプリケーションを次に実行する際は、JBossRules ツリーノードのサブ要素としてツリーの内にある以前に定義された設定を選択してJBoss Rules ボタンをクリックします。Eclipse ツールバーにはショートカットボタンが含まれており、以前の設定の 1 つをすばやく再実行できるようになっています。

結果結果

Debug ボタンをクリックすると、アプリケーションは実行を開始して、ブレークポイントに到達すると停止します。JBoss Rules のブレークポイントに到達すると、毎回該当の DRL ファイルが開きアクティブな行がハイライトされます。また、Variables ビューには、全ルールのパラメーターとその値が含まれています。デフォルトの Java デバッグアクションを使用して、次に何をするか (再開、終了、中断など) 決定することができます。デバッグビューを使用して、その時点のワーキングメモリやアジェンダのコンテンツも確認することができます。現在実行中のワーキングメモリが表示されるため、ワーキングメモリを選択する必要はありません。

バグを報告する

20.23. RULES IDE の設定

第第20章章 JBOSS DEVELOPER STUDIO

185

Page 190: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Rules IDE には、カスタマイズ可能な設定が含まれており、以下のオプションを設定することができます。

Java リソースが変更されると、すべてのルールが再度、自動的に解析されるリソースが変更されると、すべてのルールが再度、自動的に解析される

Java クラスが変更されると、すべてのルールが再度構築されるようにトリガーされます。

DRL ファイルの相互参照を可能にするファイルの相互参照を可能にする

DRL ファイルのリソースが別のファイルで定義した別のリソースを参照できるようにします。例えば、別のファイルで宣言した型を使用して、ファイルにルールを設定することができます。このオプションを有効にすると、2 つの違った DRL ファイルで同じリソース (同じパッケージ内で同じ名前を持つ 2 つのルール) を宣言することができなくなります。

内部の内部の Drools クラスの使用クラスの使用

パブリック API に公開されていない JBoss Rules クラスの使用を許可、却下、警告 (警告の生成) します。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

186

Page 191: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第21章 HELLO WORLD の例

21.1. HELLOWORLD の例: KNOWLEDGEBASE とセッションの作成

KnowledgeBuilder は DRL ソースファイルを、ナレッジベースが消費可能な Package オブジェクトに変換するために使用します。

add メソッドは Resource インターフェースとリソース型をパラメーターとして取得します。Resource は、様々な場所から DRL ソースファイルを取得するために使用できます。この場合、ResourceFactory を使用してクラスパスから DRL ファイルを取得しましたが、ディスクファイルや URL から取得数rことも可能です。

様々な名前空間の複数パッケージは、同じナレッジベースに追加することができます。

ナレッジベースはパッケージのバリデーションを行いますが、エラー情報へのアクセスは文字列としてでしか行えません。そのため、エラー情報のデバッグをするには、KnowledgeBuilder インスタンスで実行する必要があります。

ビルダーにエラーがなくなると、Package コレクションを取得して、KnowledgeBaseFactory からの KnowledgeBase をインスタンス化してパッケージコレクションに追加します。

バグを報告する

21.2. HELLOWORLD の例: イベントのロギングと監査

final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

// this will parse and compile in one stepkbuilder.add(ResourceFactory.newClassPathResource("HelloWorld.drl", HelloWorldExample.class), ResourceType.DRL);

// Check the builder for errorsif (kbuilder.hasErrors()) { System.out.println(kbuilder.getErrors().toString()); throw new RuntimeException("Unable to compile \"HelloWorld.drl\".");}

// get the compiled packages (which are serializable)final Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();

// add the packages to a KnowledgeBase (deploy the knowledge packages).final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages(pkgs);

final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

// setup the debug listenersksession.addEventListener( new DebugAgendaEventListener() );ksession.addEventListener( new DebugWorkingMemoryEventListener() ); // setup the audit logging

第第21章章 HELLO WORLD の例の例

187

Page 192: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

デフォルトのデバッグリスナーは、DebugAgendaEventListener と DebugWorkingMemoryEventListener の 2 つが提供されています。これらのリスナーは、コンソールウィンドウに表示される System.err ストリームにデバッグイベント情報を出力します。

KnowledgeRuntimeLogger は、グラフィカルビューワーで表示可能な実行監査を提供します。このロガーは、アジェンダとワーキングメモリのリスナー上に構築された特別な実装です。

エンジンの実行が完了すると logger.close() を呼び出す必要があります。

バグを報告する

21.3. HELLOWORLD の例: MESSAGE クラス

この例で使用されている単一のクラスには、メッセージ (文字列) とステータス (HELLO または GOODBYE の integer の 1 つ) のフィールド 2 つがあります。

バグを報告する

21.4. HELLOWORLD の例: 実行

単一の Message オブジェクトは、メッセージテキスト "Hello World" とステータス HELLO で作成され、エンジンに挿入されます。この時点で fireAllRules() が実行されます。

ネットワークの評価は、挿入時に行われます。プログラム実行が fireAllRules() メソッド呼び出しに到達するまでには、エンジンはどのルールが完全に一致して発火可能かすでに把握しています。

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/helloworld");

public static class Message { public static final int HELLO = 0; public static final int GOODBYE = 1;

private String message; private int status; ...}

final Message message = new Message();message.setMessage("Hello World");message.setStatus(Message.HELLO);ksession.insert(message);

ksession.fireAllRules();

logger.close();

ksession.dispose();

JBoss Rules 5 リファレンスガイドリファレンスガイド

188

Page 193: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

注記注記

Java アプリケーションとしてこの例を実行する方法:

1. Eclipse IDE で org.drools.examples.helloworld.HelloWorldExampleクラスを開きます。

2. クラスを右クリックして Run as... を選び Java application を選択します。

バグを報告する

21.5. HELLOWORLD の例: コンソールウィンドウでの SYSTEM.OUT

fireAllRules() メソッドでブレークポイントを設置して ksession 変数を選択することで、"Hello World" ルールははすでにアクティブ化され、アジェンダでパターンに一致する作業は挿入時に実行されることが分かります。

Hello Goodbye

==>[ActivationCreated(0): rule=Hello World; tuple=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]][ObjectInserted: handle=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]; object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96][BeforeActivationFired: rule=Hello World; tuple=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]]==>[ActivationCreated(4): rule=Good Bye; tuple=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]][ObjectUpdated: handle=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]; old_object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96; new_object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96][AfterActivationFired(0): rule=Hello World][BeforeActivationFired: rule=Good Bye; tuple=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]][AfterActivationFired(4): rule=Good Bye]

第第21章章 HELLO WORLD の例の例

189

Page 194: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

アプリケーションは、System.out へ移動するよう出力し、デバッグリスナーは System.err へ移動するよう出力します。

バグを報告する

21.6. HELLOWORLD の例: ルール "HELLO WORLD"

ルールの LHS (when の後ろ) 部では、ステータスが Message.HELLO のワーキングメモリに挿入された Message オブジェクトごとにルールがアクティベートされると記述されています。

また、変数バインドが 2 つ作成されています。message 変数は message 属性に、m 変数は合致した Message オブジェクト自体にバインドされています。

ルールの RHS (then の後ろ) または結果部では、ルールの属性 dialect が宣言しているように、MVEL 式言語を使用して記述されています。

System.out に message バインド変数の内容を出力した後、ルールは message の値と m にバインドされている Message オブジェクトの status 属性を変更します。

MVEL の modify ステートメントは、ブロックの最後で自動的に変更を通知するエンジンを使用して、1 つのステートメントに代入ブロックを適用することができます。

バグを報告する

21.7. HELLOWORLD の例: "DEBUG AS..." オプションの使用

手順手順21.1 タスクタスク

1. このデバッグオプションを使用するにはお使いの Eclipse IDE の org.drools.examples.HelloWorld クラスを開きます。

2. このクラスを右クリックして「Debug as...」を選択し、「Drools application」を選びます。そのルールとルールの場所の情報が表示されます。

バグを報告する

21.8. HELLOWORLD の例: ルール "GOOD BYE"

rule "Hello World" dialect "mvel" when m : Message( status == Message.HELLO, message : message ) then System.out.println( message ); modify ( m ) { message = "Goodbye cruel world", status = Message.GOODBYE };end

rule "Good Bye" dialect "java" when Message( status == Message.GOODBYE, message : message )

JBoss Rules 5 リファレンスガイドリファレンスガイド

190

Page 196: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第22章 SALIENCE ステータスの例

22.1. SALIENCE ステータスの例: STATE クラスの例

各 State クラスには、名前と現在のステータスのフィールドがあります(org.drools.examples.state.State クラス参照)。各オブジェクトで考えられる 2 つのステータスは NOTRUN と FINISHED です。

バグを報告する

22.2. SALIENCE ステータスの例: 実行

各インスタンスは順番にセッションにアサートされ、その後に fireAllRules() が呼び出されます。

バグを報告する

22.3. SALIENCE ステータスの例: アプリケーションの実行

手順手順22.1 タスクタスク

public class State { public static final int NOTRUN = 0; public static final int FINISHED = 1;

private final PropertyChangeSupport changes = new PropertyChangeSupport( this );

private String name; private int state;

... setters and getters go here...}

State a = new State( "A" );State b = new State( "B" );State c = new State( "C" );final State d = new State( "D" );

// By setting dynamic to TRUE, Drools will use JavaBean// PropertyChangeListeners so you don't have to call modify or update().boolean dynamic = true;

session.insert( a, dynamic );session.insert( b, dynamic );session.insert( c, dynamic );session.insert( d, dynamic );

session.fireAllRules();session.dispose(); // Stateful rule session must always be disposed when finished

JBoss Rules 5 リファレンスガイドリファレンスガイド

192

Page 197: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

1. Eclipse IDE の org.drools.examples.state.StateExampleUsingSalience クラスを開きます。

2. このクラスの上で右クリックして Run as... を選び Java application を選択します。以下の出力が表示されます。

バグを報告する

22.4. SALIENCE ステータスの例: オペレーションのある監査ロギングを使用

手順手順22.2 タスクタスク

1. オペレーションが生成した監査ログを表示するには、IDE を開き Window をクリックしてから Show View を選び、その後、Other...、Drools、Audit View の順に選択します。

2. "Audit View" で Open Log ボタンをクリックして <drools-examples-dir>/log/state.log ファイルを選択します。

バグを報告する

22.5. SALIENCE ステータスの例: ルール "BOOTSTRAP"

結果

全アクションと該当の変更がワーキングメモリに表示されます。

ステータス NOTRUN のステータスオブジェクト A のアサーションにより、 Bootstrap ルールがアクティベートされますが、その他の State オブジェクトのアサーションからの影響はすぐにはありません。

A finishedB finishedC finishedD finished

rule Bootstrap when a : State(name == "A", state == State.NOTRUN ) then System.out.println(a.getName() + " finished" ); a.setState( State.FINISHED );end

rule "A to B" when State(name == "A", state == State.FINISHED ) b : State(name == "B", state == State.NOTRUN ) then System.out.println(b.getName() + " finished" ); b.setState( State.FINISHED );end

第第22章章 SALIENCE ステータスの例ステータスの例

193

Page 198: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルール Bootstrap を実行すると、ステータスが A から FINISHED に変更され、ルール "A to B"をアクティベートします。

バグを報告する

22.6. SALIENCE ステータスの例: ルール "B TO C"

競合解決戦略は、エンジンのアジェンダがどのルールを発火するか決定できるようにします。

ルール "B to C" の salience 値が高い値が高いため (10 とデフォルトの salience 値 0)、先に発火されオブジェクト C をステータス FINISHED に変更します。

アジェンダビューは、ルール内にデバッグポイントを設置しアジェンダビューを開いた状態で、ジェンダーのステータスを調査するために使用することもできます。

バグを報告する

22.7. SALIENCE ステータスの例: ルール "B TO D"

ルール "B to D" は最後に発火され、オブジェクト D をステータス FINISHED に変更します。

実行するルールがないためエンジンが停止します。

バグを報告する

22.8. SALIENCE ステータスの例: 動的ファクトの挿入

エンジンがファクトのプロパティを参照して反応するには、アプリケーションがエンジンに対

rule "B to C" salience 10 when State(name == "B", state == State.FINISHED ) c : State(name == "C", state == State.NOTRUN ) then System.out.println(c.getName() + " finished" ); c.setState( State.FINISHED );end

rule "B to D" when State(name == "B", state == State.FINISHED ) d : State(name == "D", state == State.NOTRUN ) then System.out.println(d.getName() + " finished" ); d.setState( State.FINISHED );end

// By setting dynamic to TRUE, JBoss Rules will use JavaBean// PropertyChangeListeners so you don't have to call modify or update().final boolean dynamic = true;

session.insert( fact, dynamic );

JBoss Rules 5 リファレンスガイドリファレンスガイド

194

Page 199: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

して変更があったことを通知する必要があります。これは、modify ステートメントを使用してルールで明示するか、エンジンにファクトが JavaBeans specification で定義されているように PropertyChangeSupport を実装していると暗黙的に通知することで実行できます。

上記の例では、ルールに modify ステートメントを明示しないでもいいように、PropertyChangeSupport の使用方法を紹介しています。

org.drools.example.State クラスと同じように、ファクトが PropertyChangeSupportを実装するようにします。

バグを報告する

22.9. SALIENCE ステータスの例: PROPERTYCHANGESUPPORT を持つセッター

org.drools.examples クラス内の state のセッター

PropertyChangeListener オブジェクトを使用する場合、各セッターは通知用に追加でコードを実装する必要があります。

バグを報告する

22.10. SALIENCE ステータスの例: グループルール "B TO C"

結果

public void setState(final int newState) { int oldState = this.state; this.state = newState; this.changes.firePropertyChange( "state", oldState, newState );}

rule "B to C" agenda-group "B to C" auto-focus true when State(name == "B", state == State.FINISHED ) c : State(name == "C", state == State.NOTRUN ) then System.out.println(c.getName() + " finished" ); c.setState( State.FINISHED ); kcontext.getKnowledgeRuntime().getAgenda().getAgendaGroup( "B to D" ).setFocus();end

rule "B to D" agenda-group "B to D" when State(name == "B", state == State.FINISHED ) d : State(name == "D", state == State.NOTRUN ) then

第第22章章 SALIENCE ステータスの例ステータスの例

195

Page 200: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

デフォルトでは、アジェンダグループ "MAIN" にすべてのルールが入っています。

"agenda-group" 属性により、ルールに対して別のアジェンダグループを指定することができます。最初は、ワーキングメモリのフォーカスは "MAIN" に置かれています。

グループのルールは、グループにフォーカスが当たっているときのみ発火されます。setFocus() メソッドか、ルール属性 auto-focus を使用することで可能になります。

auto-focus は、ルールが合致してアクティベートされた場合に、ルールが自動的にアジェンダグループにフォーカスを設定するという意味です。"B to D" の前に "B to C" を発火できるようにするのは、この "auto-focus" なのです。

ルール "B to C" がアジェンダグループ "B to D" で setFocus() を呼び出して、アクティブなルールを発火するため、ルール "B to D" を発火させることができます。

バグを報告する

22.11. SALIENCE ステータスの例: グループルール "B TO D"

バグを報告する

22.12. SALIENCE ステータスの例: グループルール "D TO E"

この例では、以下のような出力が表示されるはずです。

System.out.println(d.getName() + " finished" ); d.setState( State.FINISHED );end

rule "B to D" agenda-group "B to D" when State(name == "B", state == State.FINISHED ) d : State(name == "D", state == State.NOTRUN ) then System.out.println(d.getName() + " finished" ); d.setState( State.FINISHED );end

rule "D to E" when State(name == "D", state == State.FINISHED ) e : State(name == "E", state == State.NOTRUN ) then System.out.println(e.getName() + " finished" ); e.setState( State.FINISHED );end

A finishedB finishedC finishedD finishedE finished

JBoss Rules 5 リファレンスガイドリファレンスガイド

196

Page 202: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第23章 フィボナッチの例

23.1. フィボナッチの例: クラス

Sequence フィールドは、フィボナッチ数の順番におけるオブジェクトの位置を指定するために使用します。

Value フィールドは、その順位のフィボナッチオブジェクトの値を表示します。算出の必要な値を指定するために -1 を使用しています。

バグを報告する

23.2. フィボナッチの例: 実行

手順手順23.1 タスクタスク

1. Eclipse IED を起動します。

2. org.drools.examples.fibonacci.FibonacciExample クラスを開きます。

3. クラスを右クリックして Run as... を選び Java application を選択します。

結果結果

Eclipse は、コンソールウィンドウに以下の出力を表示します ("...snip..." はスペースを節約するために省略された行のことです)。

public static class Fibonacci { private int sequence; private long value;

public Fibonacci( final int sequence ) { this.sequence = sequence; this.value = -1; }

... setters and getters go here...}

recurse for 50recurse for 49recurse for 48recurse for 47...snip...recurse for 5recurse for 4recurse for 3recurse for 21 == 12 == 13 == 24 == 35 == 56 == 8

JBoss Rules 5 リファレンスガイドリファレンスガイド

198

Page 203: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

23.3. フィボナッチの例: 実行の詳細

Java でこれを使用するには、Sequnce フィールドが 50 個ある Fibonacci オブジェクトを 1 つ挿入します。

再帰的なルールは、他の 49 Fibonacci オブジェクトを挿入するために使用します。

上記の例は、MVEL 方言を使用しています。つまり、modify キーワードを使用でき、エンジンに変更を通知するブロックセッターのアクションが可能となります。

バグを報告する

23.4. FIBONACCI の例: RECURSE ルール

Recurse ルールは、アサーションされた Fibonacci オブジェクトで -1 の値を持つものを照合していき、現在合致しているオブジェクトより 1 つ少ない順番の Fibonacci オブジェクトを新たに作成してアサーションします。

Fibonacci オブジェクトが追加され、Sequence フィールドが 1 のものが存在しない場合、ルールの照合と発火が再度行われます。

not の条件要素は、Fibonacci オブジェクト 50 個すべてがメモリに入った時点でルールの照合を停止するために使用します。

Recurse ルールには salience 値があるため、Fibonacci オブジェクト 50 個すべてがBootstrap ルールが実行される前にアサートされます。

監査ビューに切り替えて、Sequence フィールド 50 個持つ Fibonacci オブジェクトの元のアサーションを表示します。そこから、監査ビューはルールの反復が継続的に行われ、アサーションされた各 Fibonacci オブジェクトは Recurse オブジェクトをアクティベートして再度発火させます。

バグを報告する

...snip...47 == 297121507348 == 480752697649 == 777874204950 == 12586269025

ksession.insert( new Fibonacci( 50 ) );ksession.fireAllRules();

rule Recurse salience 10 when f : Fibonacci ( value == -1 ) not ( Fibonacci ( sequence == 1 ) ) then insert( new Fibonacci( f.sequence - 1 ) ); System.out.println( "recurse for " + f.sequence );end

第第23章章 フィボナッチの例フィボナッチの例

199

Page 204: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

23.5. FIBONACCI の例: BOOTSTRAP ルール

Sequence フィールドが 2 の Fibonacci オブジェクトがアサートされると、Bootstrap ルールがマッチし、Recurse ルールと一緒にアクティベートされます。

1 または 2 と等価かどうかをテストする sequence フィールドのマルチ制約に注目してください。

Sequence が 1 の Fibonacci オブジェクトがアサートされると、Bootstrap ルールが再度照合され、2 つのルールのアクティベーションが行われます。Fibonacci オブジェクトでsequence が 1 のものが存在すれば、not 条件要素がルールの照合を即座に停止するため、Recurse ルールの照合やアクティベーションはされません。

バグを報告する

23.6. FIBONACCI の例: CALCULATE ルール

-1 以外の値を持つ Fibonacci オブジェクトが 2 つある場合、Calculate ルールはこれらのオブジェクトと照合ができます。

ワーキングメモリに 50 の Fibonacci オブジェクトがあり、適切なオブジェクト 3 つが選択され、順番に値を算出していきます。

フィールド制約なしにルールで Fibonacci パターンを使用してクロス積候補を絞り込むと、誤ってルールを発火させることになります。Calculate ルールは、フィールド制約を使用して、正しく Fibonacci パターンを正しい順番で制約していきます。この手法は、クロス積のマッチクロス積のマッチングング (cross product matching) と呼ばれています。

最初のパターンは、値が != -1 の Fibonacci を検索して、パターンとフィールドをバインドします。2 つ目の Fibonacci も同じことを行いますが、フィールド制約が追加され f1 にバインドされた Fibonacci よりも順番が 1 つ大きくなるようにします。このルールが初めて発火される

rule Bootstrap when f : Fibonacci( sequence == 1 || == 2, value == -1 ) // multi-restriction then modify ( f ){ value = 1 }; System.out.println( f.sequence + " == " + f.value );end

rule Calculate when // Bind f1 and s1 f1 : Fibonacci( s1 : sequence, value != -1 ) // Bind f2 and v2; refer to bound variable s1 f2 : Fibonacci( sequence == (s1 + 1), v2 : value != -1 ) // Bind f3 and s3; alternative reference of f2.sequence f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 ) then // Note the various referencing techniques. modify ( f3 ) { value = f1.value + v2 }; System.out.println( s3 + " == " + f3.value );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

200

Page 205: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

と、2 つの制約により f1 は順番 1 を、f2 は順番 2 を参照するようにします。最後のパターンは、値が -1 で、順番が f2 よりも大きい Fibonacci を検索します。

使用可能なクロス積から正しく選択された Fibonacci オブジェクトが 3 つあります。f3 にバインドされた 3 番目の Fibonacci オブジェクトの値を算出することができます。

modify ステートメントは、f3 にバインドされた Fibonacci オブジェクトの値を更新します。つまり、-1 以外の値を持つ別の Fibonacci オブジェクトが新たに存在するということで、Calculate ルールにより、再度合致があるか検索して次の Fibonacci 番号を算出することができます。

監査ビューに切り替えると、最後の Bootstrap を発火することで Fibonacci オブジェクトが変更され、"Calculate" ルールが照合を開始できることが分かります。これにより、別のFibonacci オブジェクトが変更され、Calculate ルールはオブジェクトの照合を再度行います。すべての Fibonacci オブジェクトに値が設定されるまで、これが繰り返されます。

バグを報告する

第第23章章 フィボナッチの例フィボナッチの例

201

Page 206: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第24章 バンキングの例

24.1. バンキングの例: RULERUNNER

RuleRunner クラスは、データセットに対して 1 つまたは複数の DRL ファイルを実行する際に使用します。このクラスはパッケージをコンパイルして、実行毎にナレッジベースを作成して、簡単に各シナリオを実行し出力を確認できるようにします。

バグを報告する

24.2. バンキングの例: EXAMPLE1.DRL のルール

public class RuleRunner {

public RuleRunner() { }

public void runRules(String[] rules, Object[] facts) throws Exception {

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

for ( int i = 0; i < rules.length; i++ ) { String ruleFile = rules[i]; System.out.println( "Loading file: " + ruleFile ); kbuilder.add( ResourceFactory.newClassPathResource( ruleFile, RuleRunner.class ), ResourceType.DRL ); }

Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); kbase.addKnowledgePackages( pkgs ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

for ( int i = 0; i < facts.length; i++ ) { Object fact = facts[i]; System.out.println( "Inserting fact: " + fact ); ksession.insert( fact ); }

ksession.fireAllRules(); }

rule "Rule 01" when eval( 1==1 ) then System.out.println( "Rule 01 Works" );end

JBoss Rules 5 リファレンスガイドリファレンスガイド

202

Page 207: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

出力:

このルールには、eval 条件が 1 つあり、常に true となっているため、このルールは開始後に照合が行われ発火されます。

上記の出力から、ルールが 1 つの出力ステートメントに合致して実行されたことが分かります。

バグを報告する

24.3. バンキングの例: JAVA の例 2

上記の例は、基本的なファクトをアサートして出力しています。

バグを報告する

24.4. バンキングの例: EXAMPLE2.DRL のルール

出力:

Loading file: Example1.drlRule 01 Works

public class Example2 { public static void main(String[] args) throws Exception { Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)}; new RuleRunner().runRules( new String[] { "Example2.drl" }, numbers ); } private static Integer wrap( int i ) { return new Integer(i); }}

rule "Rule 02" when Number( $intValue : intValue ) then System.out.println( "Number found with value: " + $intValue ); end

Loading file: Example2.drlInserting fact: 3Inserting fact: 1Inserting fact: 4Inserting fact: 1Inserting fact: 5Number found with value: 5Number found with value: 1Number found with value: 4Number found with value: 1

第第24章章 バンキングの例バンキングの例

203

Page 208: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

これは、指定の数字を出力するという基本ルールです。Number オブジェクトで値を出力するファクトを識別します。抽象クラス Number の使用に注目してください。

パターンマッチングエンジンは、アサートしたオブジェクトのインターフェースとスーパークラスをマッチすることができます。

上記の出力は、DRL の読み込み、ファクトの挿入が終わってから、ルールの合致と発火が行われたことを表示しています。挿入した番号はそれぞれ、合致、発火後に出力されていることが分かります。

バグを報告する

24.5. バンキングの例: EXAMPLE3.JAVA

上記は、ルールをベースにした基本的な分類手法です。

バグを報告する

24.6. バンキングの例: EXAMPLE3.DRL のルール

出力:

Number found with value: 3

public class Example3 { public static void main(String[] args) throws Exception { Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)}; new RuleRunner().runRules( new String[] { "Example3.drl" }, numbers ); } private static Integer wrap(int i) { return new Integer(i); }}

rule "Rule 03" when $number : Number( ) not Number( intValue < $number.intValue ) then System.out.println("Number found with value: " + $number.intValue() ); retract( $number );end

Loading file: Example3.drlInserting fact: 3Inserting fact: 1Inserting fact: 4Inserting fact: 1Inserting fact: 5Number found with value: 1

JBoss Rules 5 リファレンスガイドリファレンスガイド

204

Page 209: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルールの最初の行は、Number を識別して値を抽出します。

2 行目で、最初のパターンで検出されたものよりも低い数値が存在しないようにします。出力後に数字を消去するというのは、最小値が削除され次に小さい数値が公開されることを指します。

バグを報告する

24.7. バンキングの例: CASHFLOW クラス

クラス Cashflow には、単純な属性が 2 つ (日付と数量) あります (浮動小数点は多くの番号を正しく表すことができないため、金額の単位に型 double を使用するのは一般的には良い慣習とは言えません。

値を設定するオーバーロードのコンストラクターと、キャッシュフローを出力するメソッド toString があります。

Number found with value: 1Number found with value: 3Number found with value: 4Number found with value: 5

public class Cashflow { private Date date; private double amount;

public Cashflow() { }

public Cashflow(Date date, double amount) { this.date = date; this.amount = amount; }

public Date getDate() { return date; }

public void setDate(Date date) { this.date = date; }

public double getAmount() { return amount; }

public void setAmount(double amount) { this.amount = amount; }

public String toString() { return "Cashflow[date=" + date + ",amount=" + amount + "]"; }}

第第24章章 バンキングの例バンキングの例

205

Page 210: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

24.8. バンキングの例: EXAMPLE4.JAVA

上記の例の Java コードは、日付と数量が異なる Cashflow オブジェクトを 5 つ挿入しています。

バグを報告する

24.9. バンキングの例: SIMPLEDATE クラス

便利な SimpleDate クラスは java.util.Date を継承して、コンストラクターが文字列を入力として受付日付形式を定義することができるようにします。

バグを報告する

24.10. バンキングの例: EXAMPLE4.DRL のルール

出力:

public class Example4 { public static void main(String[] args) throws Exception { Object[] cashflows = { new Cashflow(new SimpleDate("01/01/2007"), 300.00), new Cashflow(new SimpleDate("05/01/2007"), 100.00), new Cashflow(new SimpleDate("11/01/2007"), 500.00), new Cashflow(new SimpleDate("07/01/2007"), 800.00), new Cashflow(new SimpleDate("02/01/2007"), 400.00), }; new RuleRunner().runRules( new String[] { "Example4.drl" }, cashflows ); }}

public class SimpleDate extends Date { private static final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); public SimpleDate(String datestr) throws Exception { setTime(format.parse(datestr).getTime()); }}

rule "Rule 04" when $cashflow : Cashflow( $date : date, $amount : amount ) not Cashflow( date < $date) then System.out.println("Cashflow: "+$date+" :: "+$amount); retract($cashflow);end

JBoss Rules 5 リファレンスガイドリファレンスガイド

206

Page 211: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Cashflow が特定され、日付と数量が抽出されます。

ルールの 2 行目で、検出された日付よりも前の日付を持つ Cashflow がないことが決定します。

結果では Cashflow が出力されます。これによりルールに該当することになり削除され、次に古い Cashflow に移ります。

バグを報告する

24.11. バンキングの例: TYPEDCASHFLOW クラス

Cashflow が継承されると TypedCashflow が返され、入金または出金オペレーションのいずれかとなります。

Loading file: Example4.drlInserting fact: Cashflow[date=Mon Jan 01 00:00:00 GMT 2007,amount=300.0]Inserting fact: Cashflow[date=Fri Jan 05 00:00:00 GMT 2007,amount=100.0]Inserting fact: Cashflow[date=Thu Jan 11 00:00:00 GMT 2007,amount=500.0]Inserting fact: Cashflow[date=Sun Jan 07 00:00:00 GMT 2007,amount=800.0]Inserting fact: Cashflow[date=Tue Jan 02 00:00:00 GMT 2007,amount=400.0]Cashflow: Mon Jan 01 00:00:00 GMT 2007 :: 300.0Cashflow: Tue Jan 02 00:00:00 GMT 2007 :: 400.0Cashflow: Fri Jan 05 00:00:00 GMT 2007 :: 100.0Cashflow: Sun Jan 07 00:00:00 GMT 2007 :: 800.0Cashflow: Thu Jan 11 00:00:00 GMT 2007 :: 500.0

public class TypedCashflow extends Cashflow { public static final int CREDIT = 0; public static final int DEBIT = 1;

private int type;

public TypedCashflow() { }

public TypedCashflow(Date date, int type, double amount) { super( date, amount ); this.type = type; }

public int getType() { return type; }

public void setType(int type) { this.type = type; }

public String toString() { return "TypedCashflow[date=" + getDate() + ",type=" + (type == CREDIT ? "Credit" : "Debit") + ",amount=" + getAmount() + "]"; }}

第第24章章 バンキングの例バンキングの例

207

Page 212: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

24.12. バンキングの例: EXAMPLE5.JAVA

クラス:

ルール:

出力:

Loading file: Example5.drlInserting fact: TypedCashflow[date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]Inserting fact: TypedCashflow[date=Fri Jan 05 00:00:00 GMT 2007,type=Credit,amount=100.0]Inserting fact: TypedCashflow[date=Thu Jan 11 00:00:00 GMT 2007,type=Credit,amount=500.0]Inserting fact: TypedCashflow[date=Sun Jan 07 00:00:00 GMT 2007,type=Debit,amount=800.0]Inserting fact: TypedCashflow[date=Tue Jan 02 00:00:00 GMT 2007,type=Debit,amount=400.0]Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0Credit: Fri Jan 05 00:00:00 GMT 2007 :: 100.0

public class Example5 { public static void main(String[] args) throws Exception { Object[] cashflows = { new TypedCashflow(new SimpleDate("01/01/2007"), TypedCashflow.CREDIT, 300.00), new TypedCashflow(new SimpleDate("05/01/2007"), TypedCashflow.CREDIT, 100.00), new TypedCashflow(new SimpleDate("11/01/2007"), TypedCashflow.CREDIT, 500.00), new TypedCashflow(new SimpleDate("07/01/2007"), TypedCashflow.DEBIT, 800.00), new TypedCashflow(new SimpleDate("02/01/2007"), TypedCashflow.DEBIT, 400.00), }; new RuleRunner().runRules( new String[] { "Example5.drl" }, cashflows ); }}

rule "Rule 05" when $cashflow : TypedCashflow( $date : date, $amount : amount, type == TypedCashflow.CREDIT ) not TypedCashflow( date < $date, type == TypedCashflow.CREDIT ) then System.out.println("Credit: "+$date+" :: "+$amount); retract($cashflow);end

JBoss Rules 5 リファレンスガイドリファレンスガイド

208

Page 213: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Credit: Thu Jan 11 00:00:00 GMT 2007 :: 500.0

クラスも .drl もルールエンジンに渡されます。

クラスでは、入金または出勤のオペレーションのいずれかである Cashflow オブジェクトセットが作成されます。

Cashflow ファクトは CREDIT 型で特定され、日付と数量が抽出されます。ルールの 2 行目では、検出された日付より前で同じ型を持つ Cashflow がないことを確認します。結果では、パターンと合致する cashflow を出力してから削除し、次に古い cashflow 型に進みます。

バグを報告する

24.13. バンキングの例: ACCOUNT クラス

ルールエンジンに渡す前に、2 種の Account オブジェクトが作成され、Cashflows オブジェクトに挿入されます。

バグを報告する

24.14. バンキングの例: ALLOCATEDCASHFLOW クラス

public class Account { private long accountNo; private double balance = 0;

public Account() { }

public Account(long accountNo) { this.accountNo = accountNo; }

public long getAccountNo() { return accountNo; }

public void setAccountNo(long accountNo) { this.accountNo = accountNo; }

public double getBalance() { return balance; }

public void setBalance(double balance) { this.balance = balance; }

public String toString() { return "Account[" + "accountNo=" + accountNo + ",balance=" + balance + "]"; }}

第第24章章 バンキングの例バンキングの例

209

Page 214: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

TypedCashflow を継承すると Account を含む AllocatedCashflow となります。

バグを報告する

24.15. バンキングの例: EXAMPLE5.JAVA の継承

public class AllocatedCashflow extends TypedCashflow { private Account account;

public AllocatedCashflow() { }

public AllocatedCashflow(Account account, Date date, int type, double amount) { super( date, type, amount ); this.account = account; }

public Account getAccount() { return account; }

public void setAccount(Account account) { this.account = account; }

public String toString() { return "AllocatedCashflow[" + "account=" + account + ",date=" + getDate() + ",type=" + (getType() == CREDIT ? "Credit" : "Debit") + ",amount=" + getAmount() + "]"; }}

public class Example6 { public static void main(String[] args) throws Exception { Account acc1 = new Account(1); Account acc2 = new Account(2); Object[] cashflows = { new AllocatedCashflow(acc1,new SimpleDate("01/01/2007"), TypedCashflow.CREDIT, 300.00), new AllocatedCashflow(acc1,new SimpleDate("05/02/2007"), TypedCashflow.CREDIT, 100.00), new AllocatedCashflow(acc2,new SimpleDate("11/03/2007"), TypedCashflow.CREDIT, 500.00), new AllocatedCashflow(acc1,new SimpleDate("07/02/2007"), TypedCashflow.DEBIT, 800.00), new AllocatedCashflow(acc2,new SimpleDate("02/03/2007"), TypedCashflow.DEBIT, 400.00), new AllocatedCashflow(acc1,new SimpleDate("01/04/2007"), TypedCashflow.CREDIT, 200.00), new AllocatedCashflow(acc1,new SimpleDate("05/04/2007"), TypedCashflow.CREDIT, 300.00),

JBoss Rules 5 リファレンスガイドリファレンスガイド

210

Page 215: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

上記の Java コードは、2 つの Account オブジェクトを作成して、コンストラクターの呼び出しの各キャッシュフローにこのオブジェクトの 1 つを渡します。

バグを報告する

24.16. バンキングの例: EXAMPLE6.DRL のルール

出力:

new AllocatedCashflow(acc2,new SimpleDate("11/05/2007"), TypedCashflow.CREDIT, 700.00), new AllocatedCashflow(acc1,new SimpleDate("07/05/2007"), TypedCashflow.DEBIT, 900.00), new AllocatedCashflow(acc2,new SimpleDate("02/05/2007"), TypedCashflow.DEBIT, 100.00) }; new RuleRunner().runRules( new String[] { "Example6.drl" }, cashflows ); }}

rule "Rule 06 - Credit" when $cashflow : AllocatedCashflow( $account : account, $date : date, $amount : amount, type == TypedCashflow.CREDIT ) not AllocatedCashflow( account == $account, date < $date) then System.out.println("Credit: " + $date + " :: " + $amount); $account.setBalance($account.getBalance()+$amount); System.out.println("Account: " + $account.getAccountNo() + " - new balance: " + $account.getBalance()); retract($cashflow);end

rule "Rule 06 - Debit" when $cashflow : AllocatedCashflow( $account : account, $date : date, $amount : amount, type == TypedCashflow.DEBIT ) not AllocatedCashflow( account == $account, date < $date) then System.out.println("Debit: " + $date + " :: " + $amount); $account.setBalance($account.getBalance() - $amount); System.out.println("Account: " + $account.getAccountNo() + " - new balance: " + $account.getBalance()); retract($cashflow);end

Loading file: Example6.drlInserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Jan 01

第第24章章 バンキングの例バンキングの例

211

Page 216: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

上記の例は、日付順の cashflow が適用、算出され、残額が出力されています。

入金と出金に対して別のルールが存在しますが、以前の cashflow を確認する際の型が指定されていません。これは、すべての cashflow が cashflow の型に拘らず、日付順に適用されるようにするためです。

このような条件で、アカウントが特定され、結果 cashflow の額が更新されます。

00:00:00 GMT 2007,type=Credit,amount=300.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Feb 05 00:00:00 GMT 2007,type=Credit,amount=100.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Sun Mar 11 00:00:00 GMT 2007,type=Credit,amount=500.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Wed Feb 07 00:00:00 GMT 2007,type=Debit,amount=800.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri Mar 02 00:00:00 GMT 2007,type=Debit,amount=400.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Sun Apr 01 00:00:00 BST 2007,type=Credit,amount=200.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Thu Apr 05 00:00:00 BST 2007,type=Credit,amount=300.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri May 11 00:00:00 BST 2007,type=Credit,amount=700.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon May 07 00:00:00 BST 2007,type=Debit,amount=900.0]Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Wed May 02 00:00:00 BST 2007,type=Debit,amount=100.0]Debit: Fri Mar 02 00:00:00 GMT 2007 :: 400.0Account: 2 - new balance: -400.0Credit: Sun Mar 11 00:00:00 GMT 2007 :: 500.0Account: 2 - new balance: 100.0Debit: Wed May 02 00:00:00 BST 2007 :: 100.0Account: 2 - new balance: 0.0Credit: Fri May 11 00:00:00 BST 2007 :: 700.0Account: 2 - new balance: 700.0Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0Account: 1 - new balance: 300.0Credit: Mon Feb 05 00:00:00 GMT 2007 :: 100.0Account: 1 - new balance: 400.0Debit: Wed Feb 07 00:00:00 GMT 2007 :: 800.0Account: 1 - new balance: -400.0Credit: Sun Apr 01 00:00:00 BST 2007 :: 200.0Account: 1 - new balance: -200.0Credit: Thu Apr 05 00:00:00 BST 2007 :: 300.0Account: 1 - new balance: 100.0Debit: Mon May 07 00:00:00 BST 2007 :: 900.0Account: 1 - new balance: -800.0

JBoss Rules 5 リファレンスガイドリファレンスガイド

212

Page 218: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第25章 価格設定ルールの例

25.1. 価格設定ルールの例: 価格設定ルールの実行例

手順手順25.1 タスクタスク

1. コンソールを開きます。

2. PricingRuleDTExample.java ファイルを開き、Java アプリケーションとして実行します。コンソールウィンドウに以下の出力を表示されます。

3. 以下のコードを使用して、この例を実行します。

DecisionTableConfiguration オブジェクトの型は、 DecisionTableInputType.XLSに設定されています。

この例では Driver と Policy の 2 つのファクト型が使用されています。いずれも、デフォルト値が使用されています。Driver は 30 歳、以前に請求なし、現在のリスクプロファイル LOW となっています。適用される Policy は COMPREHENSIVE で、まだ承認されていません。

バグを報告する

25.2. 価格設定ルールの例: 決定テーブルの設定

Cheapest possibleBASE PRICE IS: 120DISCOUNT IS: 20

DecisionTableConfiguration dtableconfiguration = KnowledgeBuilderFactory.newDecisionTableConfiguration(); dtableconfiguration.setInputType( DecisionTableInputType.XLS );

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

Resource xlsRes = ResourceFactory.newClassPathResource( "ExamplePolicyPricing.xls", getClass() ); kbuilder.add( xlsRes, ResourceType.DTABLE, dtableconfiguration );

JBoss Rules 5 リファレンスガイドリファレンスガイド

214

Page 219: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

図図25.1 決定テーブルの設定決定テーブルの設定

RuleSet はパッケージ名を宣言します。その他グローバル変数には Variables、インポートクラスには Imports など、オプションのアイテムとしてここに設定できます。今回の場合は、ルールの名前空間がファクトクラスと同じであるため、省略可能です。

RuleTable 宣言 (Pricing bracket) の後の名前は生成されたルールすべての接頭辞として使用されます。

"CONDITION or ACTION" は列の目的を指します。つまり、条件の一部か、生成されるルールの結果のどちらであるかを指します。

ドライバーのデータは、3 つのセルに分かれており、そのセルの下のテンプレートの表現が適用されます。ドライバーの年齢の範囲 (コンマ区切りの値で $1 と $2 を使用)、locationRiskProfile、priorClaims がそれぞれの列で確認できます。

ポリシーベースの価格とメッセージログを Action 列に設定することができます。

バグを報告する

25.3. 価格設定ルールの例: 基本価格の算出例

第第25章章 価格設定ルールの例価格設定ルールの例

215

Page 220: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

図図25.2 基本価格の算出例基本価格の算出例

一番左の列のコメントで、広義のカテゴリーが示されます。

ドライバーの詳細は、事故歴がなく 30 歳であるため、行番号 18 と合致します。つまり、基本料金が 120 となります。

バグを報告する

25.4. 価格設定ルールの例: 割引の算出例

図図25.3 割引の算出例割引の算出例

Age 範囲、以前の請求、保険タイプから割引が出されます。

JBoss Rules 5 リファレンスガイドリファレンスガイド

216

Page 221: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ドライバーは 30 歳で以前に請求がなく、COMPREHENSIVE 保険に申し込んでいます。つまり、20% の割引が適用されます。これは、同じワークシートの別の表であるため、異なるテンプレートが適用されます。

通常のルールエンジンの仕組みがすべて適用されるため、ルールの評価は指定の順番でなくても構いません。

バグを報告する

第第25章章 価格設定ルールの例価格設定ルールの例

217

Page 222: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第26章 ペットショップの例

26.1. ペットショップの例

ペットショップの例の Java コードはすべて PetStore.java ファイルの中に含まれています。これは(Swing イベントを処理する複数のクラスに加え) 以下の主要なクラスを定義しています。

Petstore には main() メソッドが含まれています。

PetStoreUI は Swing ベースの GUI を作成、表示します。これには複数の小さいクラスが含まれており、主にマウスボタンのクリックなど様々ん GUI イベントに対応します。

TableModel には表データが含まれており、Swing クラス AbstractTableModel を継承するJavaBean です。

CheckoutCallback は GUI とルール間で対話できるようにします。

Ordershow は顧客が購入を希望するアイテムです。

Purchase には、顧客が購入する商品と商品の詳細が保存されています。

Product は、販売可能な製品と価格の詳細を含む JavaBean です。

バグを報告する

26.2. ペットショップの例: PETSTORE.MAIN での PETSTORE RULEBASE作成

上記のコードは、クラスパスの DRL ファイルからルールを読み取ります。この読み取りは、コンストラクターを使用して、PetStoreUI オブジェクトが作成される最後の 2 行で行われます。商品が集められた Vector object stock を承認します。

CheckoutCallback クラスには読み込まれた Rule Base が含まれています。

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

kbuilder.add( ResourceFactory.newClassPathResource( "PetStore.drl", PetStore.class ), ResourceType.DRL );KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

// Create the stock.Vector<Product> stock = new Vector<Product>();stock.add( new Product( "Gold Fish", 5 ) );stock.add( new Product( "Fish Tank", 25 ) );stock.add( new Product( "Fish Food", 2 ) );

// A callback is responsible for populating the// Working Memory and for firing all rules.PetStoreUI ui = new PetStoreUI( stock, new CheckoutCallback( kbase ) );ui.createAndShowGUI();

JBoss Rules 5 リファレンスガイドリファレンスガイド

218

Page 223: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

26.3. ペットショップの例: CHECKOUTCALLBACK.CHECKOUT() からのルールの発火

ルールを発火する Java コードは、CheckoutCallBack.checkout() メソッド内にあります。これは、ユーザーがチェックアウトボタンを押すと (最終的に) トリガーされます。

2 つのアイテムがこのメソッドに渡されます。1 つは GUI の一番下にある出力テキストフレームの周りにある JFrame Swing コンポーネントへのハンドルです。2 つ目は注文アイテムの一覧です。これは GUI の右上にある "Table" 部分からの情報を格納する TableModel からの情報です。

for ループは GUI からの注文アイテム一覧を Order JavaBean (PetStore.java ファイルにも含まれている) に変換します。

この例のすべてのステータスは、Swing コンポーネントに保存されています。これらのルールは実質的にステートレスとなっています。

"Checkout" ボタンを押すたびに、このコードは Swing TableModel の内容をセッションのワーキングメモリにコピーします。

ワーキングメモリに対する呼び出しは 9 個です。1 つは、ナレッジベースからステートフルナレッジセッションとして新しいワーキングメモリを作成します。次の 2 つは、ルールでグローバル変数として保持されるオブジェクトを 2 つ渡します。Swing テキスト部分と Swing フレームは、メッセージの記述に使用されます。

public String checkout(JFrame frame, List<Product> items) { Order order = new Order();

// Iterate through list and add to cart for ( Product p: items ) { order.addItem( new Purchase( order, p ) ); }

// Add the JFrame to the ApplicationData to allow for user interaction

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.setGlobal( "frame", frame ); ksession.setGlobal( "textArea", this.output );

ksession.insert( new Product( "Gold Fish", 5 ) ); ksession.insert( new Product( "Fish Tank", 25 ) ); ksession.insert( new Product( "Fish Food", 2 ) );

ksession.insert( new Product( "Fish Food Sample", 0 ) );

ksession.insert( order ); ksession.fireAllRules();

// Return the state of the cart return order.toString();}

第第26章章 ペットショップの例ペットショップの例

219

Page 224: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

他の挿入は商品に関する情報をワーキングメモリと注文一覧に保存します。最後の呼び出しは標準の fireAllRules() となっています。

バグを報告する

26.4. ペットショップの例: PETSTORE.DRL からのパッケージ、インポート、グローバル、方言

PetStore.drl ファイルの最初の部分には、様々な Java クラスをルールで使用できるようにする標準のパッケージ、import ステートメントが含まれています。

2 つの globals frame と textArea は、setGlobal() メソッドを呼び出す Java コードにより以前に渡された Swing コンポーネント JFrame と JTextArea に対する参照を保持しています。これらのグローバル変数は、セッションが生存している間、それらの値を保持します。

バグを報告する

26.5. ペットショップの例: PETSTORE.DRL からの抽出された JAVA 関数

package org.drools.examples

import org.drools.WorkingMemoryimport org.drools.examples.petstore.PetStoreExample.Orderimport org.drools.examples.petstore.PetStoreExample.Purchaseimport org.drools.examples.petstore.PetStoreExample.Productimport java.util.ArrayListimport javax.swing.JOptionPane;

import javax.swing.JFrame global JFrame frame global javax.swing.JTextArea textArea

function void doCheckout(JFrame frame, WorkingMemory workingMemory) { Object[] options = {"Yes", "No"}; int n = JOptionPane.showOptionDialog(frame, "Would you like to checkout?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);

if (n == 0) { workingMemory.setFocus( "checkout" ); } }

function boolean requireTank(JFrame frame, WorkingMemory workingMemory, Order order, Product fishTank, int total) { Object[] options = {"Yes",

JBoss Rules 5 リファレンスガイドリファレンスガイド

220

Page 225: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルールファイルにこれらの関数を設定することで、ペットショップの例がさらにコンパクトになります。

同じルールパッケージ内のファイルで、または標準の Java クラスでの静的メソッドとして関数を設定して、import function my.package.Foo.hello を使用してインポートします。

doCheckout() は、チェックアウトをするかどうかの確認ダイアログを表示します。チェックアウトする場合は、フォーカスが checkOut agenda-group にセットされ、そのグループのルールが発火できるようになります。

requireTank() は、水槽を購入するかどうかを確認するダイアログを表示します。購入する場合、新しい水槽 Product がワーキングメモリの注文リストに追加されます。

バグを報告する

26.6. ペットショップの例: PETSTORE.DRL からワーキングメモリへのアイテム追加

"No"}; int n = JOptionPane.showOptionDialog(frame, "Would you like to buy a tank for your " + total + " fish?", "Purchase Suggestion", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); System.out.print( "SUGGESTION: Would you like to buy a tank for your " + total + " fish? - " );

if (n == 0) { Purchase purchase = new Purchase( order, fishTank ); workingMemory.insert( purchase ); order.addItem( purchase ); System.out.println( "Yes" ); } else { System.out.println( "No" ); } return true;}

// Insert each item in the shopping cart into the Working Memory rule "Explode Cart" agenda-group "init" auto-focus true salience 10 dialect "java"when $order : Order( grossTotal == -1 ) $item : Purchase() from $order.itemsthen insert( $item );

第第26章章 ペットショップの例ペットショップの例

221

Page 226: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

auto-focus 属性が true を設定されているため、最初に抽出されたものが最初に発火されます。

このルールは、grossTotal が算出されていないオーダーすべてに対して照合が行われます。この順番で各購入アイテムに対してもループが行われます。ルール名、Salience (ルールの発火順の提示)、java に設定された方言など、"Explode Cart" ルールの一部はすでに説明されています。

agenda-groupinit はアジェンダグループの名前を定義します。この場合、グループにはルールが 1 つしかありません。しかし、Java コードもルール結果もこのグループにフォーカスされていないため、発火されるかどうかは、次の属性で分かります。

auto-focustrue は、fireAllRules() が Java コードから呼び出されるとこのルール (このルールは本アジェンダグループで唯一のルール) が発火可能となるようにします。

kcontext....setFocus() はフォーカスを show items と evaluate アジェンダーに順番に移していき、これらのルールが発火できるようにします。実際、この順でアイテムすべてをループしてメモリに挿入して、他のルールも挿入が終わってから発火されます。

バグを報告する

26.7. ペットショップの例: PETSTORE.DRL から GUI のアイテムを表示

show items アジェンダグループには、"Show Items" と呼ばれるルール 1 つのみが存在します(違いに注意)。現在ワーキングメモリにある注文の購入ごとに、GUI の下部分にあるテキストエリアに詳細がログされます。これに使用される textArea 変数はグローバル変数になっています。

evaluate アジェンダグループは、Explode Cart ルールからフォーカスを取得します。

バグを報告する

26.8. ペットショップの例: PETSTORE.DRL からのアジェンダグループの評価

kcontext.getKnowledgeRuntime().getAgenda().getAgendaGroup( "show items" ).setFocus(); kcontext.getKnowledgeRuntime().getAgenda().getAgendaGroup( "evaluate" ).setFocus();end

rule "Show Items" agenda-group "show items" dialect "mvel"when $order : Order( ) $p : Purchase( order == $order )then textArea.append( $p.product + "\n");end

// Free Fish Food sample when we buy a Gold Fish if we haven't already bought // Fish Food and don't already have a Fish Food Sample

JBoss Rules 5 リファレンスガイドリファレンスガイド

222

Page 227: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

"Free Fish Food Sample" ルールは、以下の状況でのみ発火されます。

店舗には魚の餌がまだ ないない。かつかつ

店舗には魚の餌のサンプルがまだ ないない。かつかつ

店舗には金魚の注文が 入っている入っている

"Suggest Tank" ルールは、以下の状況でのみ発火されます。

店舗に水槽の注文がまだ入っていない入っていない。かつかつ

店舗への注文に金魚関連の商品が 5 点以上 入っている入っている

ルールが発火されると、requireTank() 関数が発火され、ユーザーにダイアログが表示され、確定されるとタンクが注文およびワーキングメモリに追加されるようになっています。

requireTank() 関数が呼び出されると、関数に Swing GUI へのハンドルが設定されるように、ルールはグローバルの frame 変数に渡されます。

rule "Free Fish Food Sample" agenda-group "evaluate" dialect "mvel"when $order : Order() not ( $p : Product( name == "Fish Food") && Purchase( product == $p ) ) not ( $p : Product( name == "Fish Food Sample") && Purchase( product == $p ) ) exists ( $p : Product( name == "Gold Fish") && Purchase( product == $p ) ) $fishFoodSample : Product( name == "Fish Food Sample" );then System.out.println( "Adding free Fish Food Sample to cart" ); purchase = new Purchase($order, $fishFoodSample); insert( purchase ); $order.addItem( purchase ); end

// Suggest a tank if we have bought more than 5 gold fish and don't already have onerule "Suggest Tank" agenda-group "evaluate" dialect "java"when $order : Order() not ( $p : Product( name == "Fish Tank") && Purchase( product == $p ) ) ArrayList( $total : size > 5 ) from collect( Purchase( product.name == "Gold Fish" ) ) $fishTank : Product( name == "Fish Tank" )then requireTank(frame, drools.getWorkingMemory(), $order, $fishTank, $total); end

第第26章章 ペットショップの例ペットショップの例

223

Page 228: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ルールが発火されると、新しい商品 (魚の餌のサンプル) を作成して、ワーキングメモリの注文にその商品が追加されます。

バグを報告する

26.9. ペットショップの例: PETSTORE.DRL からチェックアウトを抽出

"do checkout" ルールには、アジェンダグループが設定されておらず auto-focus 属性もありません。そのため、デフォルト (MAIN) のアジェンダグループの一部とされます。明示的にフォーカスが来るように設定されているアジェンダグループのルールすべてのループが行われている間、このグループはデフォルトでフォーカスが当てられています。

このルールには LHS がないため、RHS は常に doCheckout() 関数を呼び出します。

doCheckout() 関数を呼び出すと、ルールは、関数に Swing GUI へのハンドルを設定できるように、グローバルの frame 変数を渡します。

doCheckout() 関数は、ユーザーに確認ダイアログを表示します。確定されると、関数はフォーカスを checkout アジェンダグループに移して、次のルールを多数発火できるようにします。

バグを報告する

26.10. ペットショップの例: PETSTORE.DRL からチェックアウトルール

rule "do checkout" dialect "java" when then doCheckout(frame, drools.getWorkingMemory());end

rule "Gross Total" agenda-group "checkout" dialect "mvel"when $order : Order( grossTotal == -1) Number( total : doubleValue ) from accumulate( Purchase( $price : product.price ), sum( $price ) )then modify( $order ) { grossTotal = total }; textArea.append( "\ngross total=" + total + "\n" );end

rule "Apply 5% Discount" agenda-group "checkout"dialect "mvel"when $order : Order( grossTotal >= 10 &&< 20 )then $order.discountedTotal = $order.grossTotal * 0.95; textArea.append( "discountedTotal total=" + $order.discountedTotal + "\n" );

JBoss Rules 5 リファレンスガイドリファレンスガイド

224

Page 229: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

checkout アジェンダグループには、3 つのルールがあります。

Gross Total は、商品の価格を累積して合計を出し、ワーキングメモリーに保存して textArea グローバル変数を使用して Swing JTextArea 経由で表示します。

総計が 10 から 20 の場合、Apply 5% Discount により割引合計が算出され、ワーキングメモリーに追加されてからテキスト領域に表示されます。

総計が 20 未満の場合、Apply 10% Discount により割引合計が算出され、ワーキングメモリーに追加されてからテキスト領域に表示されます。

バグを報告する

26.11. ペットショップの例: PETSTORE.JAVA の実行

PetStore.java を使用するには、以下の条件を満たす必要があります。

1. main() メソッドがルールベースの実行と読み込みを終えているが、ルールが発火されていないこと。今のところ、実行されたルールに関連する唯一のコードがこれです。

2. 新しい PetStoreUI オブジェクトが作成され、後で使用できるようにルールベースにハンドルを渡すこと。

3. Swing コンポーネントがデプロイされ、コンソールがユーザー入力を待機すること。

PetStore.java ファイルには、main() メソッドが含まれているため、コマンドラインまたは IDE で標準の Java アプリケーションとして実行できます。クラスパスが正しく設定されていることを前提としています。

最初に表示される画面は、ペットショップのデモです。ここには販売商品の一覧、選択された商品 (空の一覧)、Checkout と Reset ボタン、空のシステムメッセージ領域が含まれています。

「Checkout」ボタンを押すとビジネスルールが発火されます。

1. CheckOutCallBack.checkout() メソッドが「Checkout」ボタンが押されるのを待機している Swing クラスにより呼びだされます。これにより、TableModel オブジェクトからデータが挿入され、セッションのワーキングメモリーに挿入されます。その後、ルールを発火します。

2. 最初に発火するルールは、auto-focus が true に設定されているルールです。カート内の商品すべてに対してループして、商品がすべてワーキングメモリに保存されているようにしてか

end

rule "Apply 10% Discount" agenda-group "checkout" dialect "mvel"when $order : Order( grossTotal >= 20 )then $order.discountedTotal = $order.grossTotal * 0.90; textArea.append( "discountedTotal total=" + $order.discountedTotal + "\n" );end

第第26章章 ペットショップの例ペットショップの例

225

Page 230: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ら、Show Items と Evaluation のアジェンダグループが発火できるようにします。これらのグループのルールは、カートの中身をテキスト領域に追加して (ウィンドウの一番下)、ユーザーに魚の餌を無料で提供するか決定し、水槽を購入するかどうかの確認をします。

バグを報告する

26.12. ペットショップの例: チェックアウトルールの実行

1. Do Checkout ルールは、デフォルトの (MAIN) アジェンダグループに含まれています。常にdoCheckout() 関数関数を呼び出して 'Would you like to Checkout?' のダイアログボックスを表示します。

2. doCheckout() 関数はフォーカスを checkout アジェンダグループに設定して、そのグループにあるルールが発火できる状態にします。

3. checkout アジェンダグループのルールは、カートの中身を表示して適切な割引を適用します。

4. Swing then waits for user input は、別の商品をチェックアウトするか (再度ルールを発火させる)、GUI を終了します。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

226

Page 231: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第27章 数独の例

27.1. 数独の例: 例の読み込み

手順手順27.1 タスクタスク

1. IDE で sudoku.drl を開きます。

2. java org.drools.examples.DroolsExamplesApp を実行して SudokuExample をクリックします。ウィンドウには、空のグリッドが含まれていますが、このプログラムには読み込みや解決が可能なグリッドが複数、内部に格納されています。

3. File → Samples → Simple をクリックして例の 1 つを読み込みます。グリッドが読み込まれるまで、ボタンはすべて無効となっています。Simple の例を読み込むと、パズルの最初の状態に従いグリッドが埋められます。

4. Solve ボタンをクリックすると、JBoss Rules エンジンが残りの値を埋めていきます。このボタンは再度無効になります。

5. または、Step ボタンをクリックすると、ルールセットで検索された次の数字を確認できます。コンソールウィンドウで、以下の例のように解読可能な形式で、このステップの解決に実行されるルールに関する詳細情報が表示されます。

single 8 at [0,1]column elimination due to [1,2]: remove 9 from [4,2]hidden single 9 at [1,2]row elimination due to [2,8]: remove 7 from [2,4]remove 6 from [3,8] due to naked pair at [3,2] and [3,7]hidden pair in row at [4,6] and [4,4]

6. Dump ボタンをクリックするとグリッドの状態が表示されます。このセルは解決済みの値か残りの候補値を表示します。以下の例をご覧ください。

Col: 0 Col: 1 Col: 2 Col: 3 Col: 4 Col: 5 Col: 6 Col: 7 Col: 8 Row 0: 2 4 7 9 2 456 4567 9 23 56 9 --- 5 --- --- 1 --- 3 67 9 --- 8 --- 4 67 Row 1: 12 7 9 --- 8 --- 1 67 9 23 6 9 --- 4 --- 23 67 1 3 67 9 3 67 9 --- 5 --- Row 2: 1 4 7 9 1 456 --- 3 --- 56 89 5 78 5678 --- 2 --- 4 67 9 1 4 67 Row 3: 1234 12345 1 45 12 5 8 --- 6 --- 2 5 78 5 78 45 7 --- 9 --- Row 4: --- 6 --- --- 7 --- 5 --- 4 --- 2 5 8 --- 9 --- 5 8 --- 1 --- --- 3 --- Row 5: --- 8 --- 12 45 1 45 9 12 5 --- 3 --- 2 5 7 567 4567 2 4 67 Row 6: 1 3 7 1 3 6 --- 2 --- 3 56 8 5 8 3 56 8 --- 4 --- 3 567 9 1 678 Row 7: --- 5 --- 1 34 6 1 4 678 3 6 8 --- 9 --- 34 6 8 1 3 678 --- 2 --- 1 678 Row 8: 34 --- 9 --- 4 6 8 --- 7 --- --- 1 --- 23456 8 3 56 8 3 56 6 8

第第27章章 数独の例数独の例

227

Page 232: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

バグを報告する

27.2. 数独の例: 壊れた内容のデバッグ例

手順手順27.2 タスクタスク

1. IDEで sudoku.drl を開きます。

2. File → Samples → !DELIBERATLEY BROKEN! をくりっくします。JBoss Rules エンジンは、グリッドを確認して以下の出力を生成します。

cell [0,8]: 5 has a duplicate in row 0cell [0,0]: 5 has a duplicate in row 0cell [6,0]: 8 has a duplicate in col 0cell [4,0]: 8 has a duplicate in col 0Validation complete.

3. Solve ボタンをクリックして、この無効なグリッドに回答ルールを適用します。これらのルールは問題解決にセルの値を使用します。このような状況を検出するルールはし知恵のセルの解決値など Setting ファクトを挿入します。このファクトは、グループ内の全セルから不正な値を削除します。

バグを報告する

27.3. 数独の例: JAVA ソースおよびルール

Java ソースコードは、/src/main/java/org/drools/examples/sudoku ディレクトリにあり、ルールを定義する 2 つの DRL ファイルは /src/main/rules/org/drools/examples/sudoku ディレクトリにあります。

org.drools.examples.sudoku.swing パッケージには、数独パズルのフレームワークを実装するクラスセットが含まれています。このパッケージには、JBoss Rules ライブラリとの依存関係はありません。

SudokuGridModel は、9x9 グリッドの Cell オブジェクトとして数独パズルを格納するために実装可能なインターフェースを定義しています。

SudokuGridView は Swing コンポーネントで SudokuGridModel 実装の視覚化が可能です。

SudokuGridEvent と SudokuGridListener は、モデルとビューの間のステータスの変化をやり取りするために使用します。セルの値が解決または変更されると、イベントが発火されます。

SudokuGridSamples は、デモ用に一部入力されている数独パズルを複数提供します。

org.drools.examples.sudoku.rules パッケージには、DRL ファイルのコンパイル用のメソッドとユーティリティクラスが含まれています。

org.drools.examples.sudoku パッケージには、初級の Cell オブジェクトと様々な累積を実装するクラスが含まれています。これには、CellFile サブタイプ CellRow、 CellCol、CellSqr が含まれています (これらは CellGroup サブタイプとなっています)。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

228

Page 233: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

27.4. 数独の例: CELL オブジェクト

Cell と CellGroup は SetOfNine のサブクラスで、Set<Integer> 型の free プロパティを提供します。Cell は、個別の候補セットを表します。CellGroup は、セルの全候補セットの統合または、割り当ての必要のある数値セットです。

特定の状況を検出して、セルへの値の割り当て、候補セットからの値の削除などを許可するルールを記述します。例えば、Cell オブジェクトは 81 の Cell と 27 の CellGroup オブジェクトを持つリストを作成することができます。また、Cell プロパティである cellRow、cellCol、cellSqr と the CellGroup プロパティの cells からのリンクを組み合わせることも可能です。

バグを報告する

27.5. 数独の例: クラスとオブジェクト

Setting クラスに所属するオブジェクトは、値の割り当てに伴うオペレーションをトリガーするために使用します。Setting ファクトは、プロセスの変更を検出するすべてのルールに使用します。これは、中間のステータスに整合性がとれない場合などに反応しないようにするためです。

Stepping クラスのオブジェクトは、優先順位が低いルールに使用して、"step" が予期なく中断された場合に緊急停止を行います。これは、プログラムでパズルを解決できないということです。

org.drools.examples.sudoku.SudokuExample クラスは、上記のコンポーネントを組み合わせる Java アプリケーションを実装します。

バグを報告する

27.6. 数独の例: VALIDATE.DRL

Sudoku Validator Rules (validate.drl) は、セルグループで重複している番号を検出します。アジェンダグループで組み合わせて、パズルの読み込みした後にアクティベートできるようにします。

3 つの duplicate in cell... ルールは非常によく似ています。最初のパターンは、割り当てた値でセルの場所を検索します。2 番目のパターンは、セルが所属するセルグループ 3 つのいずれかをプルします。最後のパターンは、同じ行、列、四角の中でそれぞれ、最初のセルと同じ値を持つセルを検索します。

terminate group ルールを最後に発火します。メッセージを出力して halt を呼び出します。

バグを報告する

27.7. 数独の例: SUDOKU.DRL

Sudoku.drl にはルール解決のタイプが 3 種類あります。1 つは、グループがセルへの数値の割り当てを処理して、もう 1 つは実行可能な割り当てを検出して、3 つ目は候補セットからの値を削除します。

set a value、eliminate a value from Cell、retract setting のルールは、Setting オブジェクトがあるかどうかにより左右されます。

第第27章章 数独の例数独の例

229

Page 234: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

Set a value は、セルへの割り当てやセルの 3 つのグループの "free" セットから値を削除する操作を処理します。また、ゼロの場合には fireUntilHalt() が呼び出された Java アプリケーションへの制御を返すカウンターを 1 つ減らします。

Eliminate a value from Cell は、新しく割り当てられたセルに関する全セルの候補リストを減らします。

Retract setting は、削除がすべて終わると Setting ファクトのトリガーを削除します。

セルに数字を割り当てることができる状況を割り出すルールは 2 つだけです。single ルールは、数字が 1 つだけの候補セットを含む Cell の場合に発火します。hidden single ルールは、候補があっても、セルが所属するグループの 1 つに含まれるその他すべてのセルにkの候補が含まれていない場合に発火されます。これらのルールはいずれも Setting ファクトを作成、挿入します。

ルールの最大のグループからのルールは、様々な解決手法を 1 つまたは 2-3 のグループ単位で実装します。これは、数独パズルが手動で解決された場合に使用されるためです。

naked pair ルールは、グループの 2 つのセルで全く同じ候補セットを 2 つ検出します。これら 2 つの値は、そのグループのその他の全候補セットから削除することができます。

hidden pair in ルールでは、ルールはグループの 2 つのセルで 2 つの数字を探します。どの値もこのグループの他のセルには入りません。つまり、他の候補はすべて、隠れたペアを持つ 2 つのセルから削除します。

ルールのペアは、列と行内の X-wings を処理します。行 (または列) 2 つの値に対して考えられるセルが 2 つしかない場合、これらの候補は同じ行 (または列) に入れられ、この行 (または列) でこの値に対する他の候補すべてが削除されます。条件 same または only は、適切な制約を持つパターンになるか、not の接頭辞がつきます。

intersection removal... のルールペアは、1 つの四角の中に (1 つの行または列) 使用できる数字を制限するというルールに基づいています。つまり、この番号は行または列の中の 2-3セルの 1 つに入っていないといけないのです。グループの別のセルすべての中にある候補セットから削除できます。このパターンは、発生制限を確立して、同じセルファイルの中かつ、四角の外のセルそれぞれに対して発火されます。

非常に困難なグリッドを解決するには、ルールセットはより複雑なルールで拡張する必要があります (最終的には、試行錯誤でしか解決できないパズルもあります)。

バグを報告する

JBoss Rules 5 リファレンスガイドリファレンスガイド

230

Page 235: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

第28章 数字当ての例

28.1. 数字当ての例: サンプルの読み込み

NumberGuess.drl にある数字当てのサンプルでは、ルールフローの用途、ルール発火の順番を制御する方法などが説明されています。上記のように読み込まれます。

バグを報告する

28.2. 数字当ての例: RULEFLOW の開始

上記のコードは、パッケージの作成とルールの読み込みの例です (add() メソッドの使用)。

ルールフローを追加する (NumberGuess.rf) 行が 1 つ増えており、同じナレッジベースに別のルールフローを指定するオプションが追加されます。

ナレッジベースが作成されると、ステートフルセッションの取得に使用できます。その後ファクトが挿入されます。

バグを報告する

final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.drl", ShoppingExample.class ), ResourceType.DRL );kbuilder.add( ResourceFactory.newClassPathResource( "NumberGuess.rf", ShoppingExample.class ), ResourceType.DRF );

final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/numberguess");

ksession.insert( new GameRules( 100, 5 ) );ksession.insert( new RandomNumber() );ksession.insert( new Game() );

ksession.startProcess( "Number Guess" );ksession.fireAllRules();

logger.close();

ksession.dispose();

第第28章章 数字当ての例数字当ての例

231

Page 236: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

28.3. 数字当ての例: クラスとメソッド

注記注記

数字当てサンプルのクラスはすべて NumberGuessExample.java ファイルに含まれています。

GameRules クラスでは、数当ての最大範囲と何度まで推理できるかを決定します。

RandomNumber クラスは、0 から 100 までの数字を自動生成して、ルールで使用できるようにします。getValue() メソッドを使って挿入をすることで行います。

Game クラスは、推理した回数をトラッキングします。

startProcess() メソッドを呼び出して、プロセスを開始します。

ルールの実行には fireAllRules() メソッドが呼び出されます。

ワーキングメモリセッションの削除には、dispose() メソッドが呼び出されます。

バグを報告する

28.4. 数字当ての例: RULEFLOW の確認

手順手順28.1 タスクタスク

1. Drools IDE で NumberGuess.rf ファイルを開きます。標準的なフローチャートのように機能する図が表示されます。

2. この図を編集するには、IDE の図の左側にある、使用可能なコンポーネントメニューを使用します。これは パレット と呼ばれます。

3. XML でこの図を保存します (XStream がインストールされている場合は使用することができます)。

4. まだ開いてない場合は、IDE で Properties View が表示されるようにしてください。Window →Show View → Other をクリックして開き、ここから Properties ビューを選択します。ルールフローのアイテムを選択する (ルールフローのスペースをクリックする) 前前にこれを行うとプロパティが表示されます。これらのプロパティを使用して、プロセスの特定や変更の確認を行うことができます。

バグを報告する

28.5. 数字当ての例: RULEFLOW ノード

数字当ての RuleFlow には、ノード型が複数あります。

開始ノード (緑の丸の中に白い矢印) と終端ノード (赤い箱) は、ルールフローの最初と最後を表しています。

ルールフローグループのボックス (アイコンなし、黄色) は、ルール (DRL) ファイルで定義されたルールフローグループを指します。例えば、フローがルールフローグループ "too high" に到達すると、属性が ruleflow-group"Too High" とマーキングされているルールのみが発火

JBoss Rules 5 リファレンスガイドリファレンスガイド

232

Page 237: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

できるようになります。

アクションノード (黄色い歯車の形をしたアイコン) は標準の Java メソッド呼び出しを実行します。このサンプルにある多くのアクションノードは System.out.println() を呼び出し、プログラムの進捗をユーザーに表示します。

"Guess Correct?" や "More guesses Join" マークなどの分割ノードと結合ノード (青い楕円、アイコンなし) は、制御フローが分割、結合できる場所に設置されます。

矢印は、様々なノードとノードの間のフローを指します。

バグを報告する

28.6. 数当ての例: NUMBERGUESS.DRL の特定のポイントでのルールの発火

ルールと様々なノードを組み合わせることで、数当てゲームが機能します。例えば、"Guess"ルールフローグループは、"Get user Guess" ルールしか同じ ruleflow-group"Guess" 属性を持たないためこのルールだけを発火させることができます。

ルールの LHS のセクション (when の後の部分) は、RandomNumber オブジェクトがワーキングメモリに挿入されるたびにアクティベートされると記述しています。つまり、guessCountが GameRules からの allowedGuesses より多く、正しい数字を推理していない場合です。

RHS のセクション (または結果、then の後ろの部分) はユーザーにメッセージを出力して System.in からのユーザー入力があるまで待機します。この入力を取得すると (readLine()メソッド呼び出しは Return キーが押されるまでブロック)、推理回数を変更して新たな推理を挿入し、両方をワーキングメモリで使用できるようにします。

このパッケージでは、方言を MVEL で宣言し、様々な Java クラスがインポートされています。

合計で、このファイルにはルールが 5 つあります。

rule "Get user Guess" ruleflow-group "Guess" no-loop when $r : RandomNumber() rules : GameRules( allowed : allowedGuesses ) game : Game( guessCount < allowed ) not ( Guess() ) then System.out.println( "You have " + ( rules.allowedGuesses - game.guessCount ) + " out of " + rules.allowedGuesses + " guesses left.\nPlease enter your guess from 0 to " + rules.maxRange ); br = new BufferedReader( new InputStreamReader( System.in ) ); i = br.readLine(); modify ( game ) { guessCount = game.guessCount + 1 } insert( new Guess( i ) );end

第第28章章 数字当ての例数字当ての例

233

Page 238: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

1. ユーザーに推測させるルール (上記でルールは検証済み)。

2. 一番推理の回数が多いものを記録するルール。

3. 一番推理の回数が少ないものを記録するルール。

4. 推理した数字を検証して間違っている場合はメモリから削除するルール。

5. 最大で推理が試行できる回数をすべて使い果たしたことをユーザーに通知するルール。

バグを報告する

28.7. 数字当ての例: RULEFLOW の制約の確認

手順手順28.2 タスクタスク

1. IDE で Properties ビューに移動して "Constraints" プロパティの行をクリックしてConstraints Editor を開きます。

2. To node Too High の横の Edit ボタンをクリックして、様々なオプションが含まれているダイアログを開きます。Textual Editor ウィンドウの値は、LHS の標準ルール形式に従い、ワーキングメモリのオブジェクトを参照します。LHS の式が True と評価された場合、結果 (RHS) では制御のフローがこのノードに従います (To node Too High)。

バグを報告する

28.8. 数字当ての例: コンソールの出力

You have 5 out of 5 guesses left.Please enter your guess from 0 to 10050Your guess was too highYou have 4 out of 5 guesses left.Please enter your guess from 0 to 10025Your guess was too lowYou have 3 out of 5 guesses left.Please enter your guess from 0 to 10037Your guess was too lowYou have 2 out of 5 guesses left.Please enter your guess from 0 to 10044Your guess was too lowYou have 1 out of 5 guesses left.Please enter your guess from 0 to 10047Your guess was too lowYou have no more guessesThe correct guess was 48

JBoss Rules 5 リファレンスガイドリファレンスガイド

234

Page 239: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

ファイル NumberGuess.java には main() メソッドが含まれているため、コマンドラインまたは IDE から標準の Java アプリケーションとして実行できます。一般的なゲームであれば、上記のような対話が行われるでしょう。太字の数字はユーザーが入力したものです。

NumberGuessExample.java の main() メソッドはルールベースを読み込み、ステートフルセッションを作成して、そのセッションに Game、GameRules、RandomNumber (正解となる数字) オブジェクトを挿入します。このメソッドは使用するプロセスフローを設定して、すべてのルールを発火します。RuleFlow に制御が移動します。

RuleFlow ファイル NumberGuess.rf は "Start" ノードから開始します。

Guess ノードで、適切な Rule Flow Group ("Get user Guess") が有効になります。この場合(NumberGuess.drl ファイル内の) "Guess" ルールがトリガーされます。このルールは、ユーザーにメッセージを表示して、応答を受け取りワーキングメモリに挿入します。フローは、次の Rule Flow ノードに移ります。

次のノード "Guess Correct" 制約が現在のセッションをチェックしてどのパスをたどるかを決定します。

ステップ 4 で推理した数字が大きすぎる/小さすぎる場合、フローは、通常の Java コードを使用するアクションノードがあるパスに進み適切なメッセージを出力して、Rule Flow Group が最大推理回数または最小推理回数ルールをトリガーします。フローはこれらのノードからステップ 6 に移ります。

ステップ 4 の推理が正しい場合、RuleFlow の終端へのパスを進んでいきます。これの前に、通常の Java コードを使用するアクションノードが "You guessed correctly" とう文章を出力します。ここでは結合ノードがあるため (ルールフローが終了する直前)、no-more-guesses パス(ステップ 7) も RuleFlow を終了することができます。

結合ノードを経由して RuleFlow に従い制御が "guess incorrect" RuleFlow Group に移動し(ワーキングメモリから推理を削除するルールをトリガー)、”More Guesses" の決定ノードに移動します。

"More guesses" の決定ノード (ルールフローの右側) は制約を使用し、ルールがワーキングメモリに挿入した値を確認し、ユーザーが推理ゲームを継続できるかどうかを決定します。継続できる場合、ステップ 3 に進みます。できない場合、"you have no more guesses" と表示するルールをトリガーする RuleFlow Group を通り、RuleFlow の最後に進みます。

ステップ 3 から 7 までのループは、数字が正しく推理されるか、ユーザーが最大推理回数に到達するまで、継続されます。

バグを報告する

第第28章章 数字当ての例数字当ての例

235

Page 240: JBoss Enterprise BRMS Platform 5...8.7. 別のプロセスでの構築およびデプロイメント 8.8. OUTPUTSTREAM への KNOWLEDGEPACKAGE の記述 8.9. INPUTSTREAM から KNOWLEDGEPACKAGE

付録A 改訂履歴

改訂改訂 5.0.0-1 Wed Jan 15 2014 CS Builder RobotBuilt from Content Specification: 12778, Revision: 507496

JBoss Rules 5 リファレンスガイドリファレンスガイド

236