Jess notes 6カスタムルール(3)

3398 ワード

6.15.'accumulate'条件要素
「accumulate」条件要素は複雑で理解しにくいが、非常に強い.factのカウント、fieldsの統計、collectionなどに使用できます.以下では簡単に説明します.
accumulate CE構文規則は次のとおりです.
(accumulate)マッチング中にaccumulate CEに遭遇した場合(特にpreceding patternマッチングの場合、またはその含まれるCEマッチングの場合)は、次のイベントが発生します.
1.新しい実行コンテキスト(execution context)を作成します.
2.context初期化.
3.CEがLHSによって活性化されると、対応するmemoryから取り出されたすべての一致識別子が含まれる.RHSでアクティブ化されている場合、一致するLHSはそれぞれアクセスされます.それぞれがアクセスされるため、それに対応するRHSもすべてアクセスされる.
4.各考慮されたtokenは、定義された変数が実行コンテキスト(execution context)にバンドルされ、実行される.
5.現在patternがバインドされている場合、結果は指定した変数にバインドされます.
6.最後に、accumulate CEマッチングは円満に完了し、次の条件要素のマッチングを継続する.
 
上記のイベントから、「accumulate」を使用すると、マッチングごとに対応するコードが実行され、accumulatedの結果が返されることがわかります.たとえば、次のruleは、年収100000ドルを超える従業員をカウントします.0に初期化された変数で、一致するたびに自動的に1が加算され、pattern bindingにバインドされます.
Jess> (deftemplate employee (slot salary) (slot name))
Jess> (defrule count-highly-paid-employees
	?c <- (accumulate (bind ?count 0) ;; initializer
	(bind ?count (+ ?count 1)) ;; action
	?count ;; result
	(employee (salary ?s&:(> ?s 100000)))) ;; CE
	=>
	(printout t ?c " employees make more than $100000/year." crlf))

 
以下の変換後、条件を満たす従業員リストを印刷するのではなく、ArrayListにすべての名前を格納します.
Jess> (defrule count-highly-paid-employees
	?c <- (accumulate (bind ?list (new java.util.ArrayList)) ;; initializer
	(?list add ?name) ;; action
	?list ;; result
	(employee (name ?name)
	(salary ?s&:(> ?s 100000)))) ;; CE
	=>
	(printout t (?c toString) crlf))

 
注意:1つのfactを一致させると、accumulateが他の多くのfactに対して繰り返し演算し、計算オーバーヘッドが大きすぎる可能性があります.そのため、慎重に使う必要があります.
 
6.16.'Unique'条件要素
Unique CEはキャンセルされました.このパラメータは構文エラーは発生しませんが、実行されません.
 
6.17.ノードインデックスhash値(node index hash value)
Node index hash valueは、グローバルパラメータまたはruleごとに個別に設定できる調整可能なパフォーマンスパラメータです.設定した値が小さいほどメモリの消費量は小さくなりますが、パフォーマンスの犠牲になる可能性があります.設定した値が大きいほどメモリ容量が大きくなりますが、ruleのLHSの実行速度が速くなります.
通常ruleに大きな値を設定すると、多くの部分的なマッチングが発生する可能性があります(質量数を選択することが望ましい).
Jess> (defrule nihv-demo
	(declare (node-index-hash 169))
	(item ?a)
	(item ?b)
	(item ?c)
	(item ?d)
	=>)

 
詳細な使用方法については、set-node-index-hash関数を参照してください.
 
6.18.deftemplateの'slot-specific'宣言
defrulesと同様に、deftemplateの定義には宣言(declare)セクションを含めることができます.ここでは、さまざまなプロパティを宣言できます.そのうちの1つは「slot-specific」です.このような説明を伴うtemplateのマッチング方式も異なっている:このようにtemplateによってruleのLHSとマッチングして修正されるfactが構築される場合、その結果は修正されたslotがpatternで定義され、factにマッチングするために使用されるかどうかに依存する.次の例を示します.
Jess> (deftemplate D (declare (slot-specific TRUE)) (slot A) (slot B))
Jess> (defrule R
	?d <- (D (A 1))
	=>
	(modify ?d (B 3)))

 
「slot-specific」宣言を使用しない場合、ruleは無限ループに陥ります.LHSと一致するfactを修正し、修正されたfactは依然として一致しているからである.この宣言により、一度だけ実行できます.これは多くの初心者が望んでいるデフォルト設定であり、この現象の科学用語は反射(refraction)と呼ばれている.
 
6.19.ruleの「no-loop」宣言
1つのruleが宣言(declare(no-loop TRUE))を含む場合、ruleは再アクティブ化されずに実行されます.特に、no-loop ruleがfactと一致し、ruleが同じfactを変更してもfactは一致しますが、ruleは再実行されず、無限ループを回避します.実質的には「slot-specific」の強化形式である.