爲了證明點火順序不會影響整體結果,我會使用AgendaFilter。我正在使用6.x來勾畫大綱,但自從5.x以來,這個API並沒有改變。
KieBase kieBase = ...;
Collection<KiePackage> packages = kieBase.getKiePackages();
List<Rule> rules = new ArrayList<>();
for(KiePackage p: packages){
rules.addAll(p.getRules());
}
現在你有所有的規則。建立這個簡單的過濾器,它接受一個規則:
class Selector implements AgendaFilter {
List<Rule> rules;
int ruleIndex;
Selector(List<Rule> rules){
this.rules = rules;
}
void setRuleIndex(int value){ this.ruleIndex = value; }
int getRulesSize(){ return rules.size(); }
boolean accept(Match match){
return match.getRule().equals(rules.get(ruleIndex));
}
}
實例化:
Selector selector = newSelector(rules);
現在你可以被激活的所有規則(見下文):
for(int i = 0; i < selector.getRulesSize(); ++i){
int fired = kieSession.fireAllRules(selector, i);
}
任何其他0..size-1的置換可能會產生另一個發射序列。您可以爲少數規則系統地執行此操作,也可以使用一些隨機排列。
更高效的測試將跟蹤在第一次運行時傳遞給過濾器的匹配數據,並僅將這些數據用於後續執行。
注意到目前爲止概述的方法在工作內存中不考慮更改。規則n可能會被激活,當某些規則n + k被觸發。如果你確實有工作記憶的變化,你必須
do {
int sumf = 0;
for(int i : somePermutation){
int fired = kieSession.fireAllRules(selector, i);
sumf += fired;
}
} while(sumf > 0);
我從來沒有做過這樣的測試。看來,根據規則解除的先天順序來獲得正確的結果是非常罕見的,與從這個順序中得到各種錯誤結果形成對比。
注意規則觸發順序的其他排列由DRL改變規則的順序(或在他們的包?),或者通過改變事實的插入順序進入工作記憶是可能的。對於某些情況,即使這可能會提供足夠的測試用例來顯示您的意圖。
此鏈接指向相當古老的信息。 - 你有改變衝突解決方案的切實原因嗎? – laune
我想說明的是,觸發規則的順序對系統輸出沒有任何影響。是否有另一種按隨機順序執行規則的方法? – kedzia