從網上下載最新版的 SRE也是06年的了。 並且代碼中的測試用例和邏輯不搭邊。經過仔細研究,作出一個靠譜的例子可以讓系統跑起來,而後又能夠提現程序功能的。 架構
RuleExample.xml 文件 ide <?xml version="1.0" encoding="utf-8" ?> post <RuleEngine><Rules> <Rule id="Rule1" desc="" chainable="True"> <Condition><![CDATA[ NOT(F2>F1) ]]></Condition> <Actions> <Evaluate factId="F2"><![CDATA[ F2+1 ]]></Evaluate> <Execute factId="Rule2" /> </Actions> </Rule> <Rule id="Rule2" desc=""> <Condition><![CDATA[ 1==1 ]]></Condition> <Actions Result="True"> <Evaluate factId="Result"><![CDATA[ True ]]></Evaluate> </Actions> </Rule> <Rule id="Rule3" desc="" chainable="True"> <Condition><![CDATA[ 1==1 ]]></Condition> <Actions Result="True"> <Evaluate factId="Result"><![CDATA[ True ]]></Evaluate> </Actions> </Rule> </Rules> <Facts> <Fact id="F1" desc="1" type="double" modelId="bob"> <xpath><![CDATA[ a/number1 ]]></xpath> </Fact> <Fact id="F2" desc="2" type="double" modelId="bob"> <xpath><![CDATA[ a/number2 ]]></xpath> </Fact> <Fact id="True" desc="True" type="boolean" modelId="bob"> <xpath><![CDATA[ boolean(1) ]]></xpath> </Fact> <Fact id="False" desc="False" type="boolean" modelId="bob"> <xpath><![CDATA[ boolean(0) ]]></xpath> </Fact> <Fact id="Result" desc="Result" type="boolean" modelId="bob"> <xpath><![CDATA[ a/result2 ]]></xpath> </Fact> </Facts> </RuleEngine> |
static void Main(string[] args) { 測試 //規則XmlDocument rules = new XmlDocument(); string directory = AppDomain.CurrentDomain.BaseDirectory + @"\..\..\..\RuleExample.xml";//規則鏈條 rules.Load(directory); ROM rom = Compiler.Compile(rules); //模型 XmlDocument model = new XmlDocument(); model.LoadXml("<a><number1>10</number1><number2>1</number2><result2/></a>"); rom.AddModel("bob", model); Console.WriteLine("Starting Test:" + DateTime.Now); //解析所有規則計算 rom.Evaluate(); } this
|
分爲3層來看。 lua
1.接口Ievidence。 spa
2.Aevidence 、 Ifact、IRules、IAction .net
3.繼承:三個I接口與Aevidence結合 : AEvidence, IAction 設計
獲得 三個類。 Fact、Rule、Action的三個類。 調試
Action類中ActionExpression 行爲表達式解析,方程式求值。
做爲存儲內容的值
1.接口Ievidencevalue
2.Naked 繼承自Ievidencevalue
做爲表達式解析思想的核心類。
ExpressionEvaluator類
做爲推理過程的核心方法:
Decision類 中的Evaluate 方法。
經過上面的例子,修改了一部分輸出代碼。能跑出來中間輸出結果爲:
Execution List: F1, Result, True, F2, False, Rule3, Rule1 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: Result, True, F2, False, Rule3, Rule1 Processing EvidenceId: Result End Processing Execution List: False, F1, True, F2, Rule3, Rule1 Processing EvidenceId: False End Processing Execution List: F2, Result, F1, True, Rule3, Rule1 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, False, Result, F1, Rule3, Rule1 Processing EvidenceId: True End Processing Execution List: F1, F2, False, Result, Rule3, Rule1 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: F2, False, Result, Rule3, Rule1 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Result, Rule3, Rule1 Processing EvidenceId: False End Processing Execution List: Result, Rule3, Rule1 Processing EvidenceId: Result End Processing Execution List: Rule3, Rule1 Processing EvidenceId: Rule3 ExpressionEvaluator 1 == 1 = True 增長證據執行列表: Rule3-Result-0 End Processing Execution List: Rule3-Result-0, Rule1 Processing EvidenceId: Rule3-Result-0 FACT Result=True 增長證據執行列表: Result End Processing Execution List: F1, Result, True, F2, False, Rule1 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: Result, True, F2, False, Rule1 Processing EvidenceId: Result End Processing Execution List: True, F2, False, Rule1 Processing EvidenceId: True End Processing Execution List: F2, False, Rule1 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1 Processing EvidenceId: False End Processing Execution List: Rule1 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 1 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 1 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 1 ExpressionEvaluator 1 + 1 = 2 FACT F2=2 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 2 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 2 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 2 ExpressionEvaluator 2 + 1 = 3 FACT F2=3 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 3 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 3 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 3 ExpressionEvaluator 3 + 1 = 4 FACT F2=4 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 4 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 4 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 4 ExpressionEvaluator 4 + 1 = 5 FACT F2=5 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 5 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 5 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 5 ExpressionEvaluator 5 + 1 = 6 FACT F2=6 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 6 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 6 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 6 ExpressionEvaluator 6 + 1 = 7 FACT F2=7 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 7 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 7 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 7 ExpressionEvaluator 7 + 1 = 8 FACT F2=8 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 8 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 8 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 8 ExpressionEvaluator 8 + 1 = 9 FACT F2=9 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 9 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 9 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 9 ExpressionEvaluator 9 + 1 = 10 FACT F2=10 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 10 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 10 > 10 = False ExpressionEvaluator NOT False = True 增長證據執行列表: Rule1-F2-0 增長證據執行列表: Rule1-Rule2-1 End Processing Execution List: Rule1-Rule2-1, Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-Rule2-1 增長證據執行列表: Rule2 End Processing Execution List: Rule1-F2-0, Rule2 Processing EvidenceId: Rule1-F2-0 ExpressionEvaluator FACT F2 = 10 ExpressionEvaluator 10 + 1 = 11 FACT F2=11 增長證據執行列表: F2 End Processing Execution List: F1, F2, False, True, Result, Rule2 Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: True, Result, F2, False, Rule1, Rule2 Processing EvidenceId: True End Processing Execution List: Result, F2, False, Rule1, Rule2 Processing EvidenceId: Result End Processing Execution List: F2, False, Rule1, Rule2 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Rule1, Rule2 Processing EvidenceId: False End Processing Execution List: Rule1, Rule2 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 11 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 11 > 10 = True ExpressionEvaluator NOT True = False End Processing Execution List: Rule2 Processing EvidenceId: Rule2 ExpressionEvaluator 1 == 1 = True 增長證據執行列表: Rule2-Result-0 End Processing Execution List: Rule2-Result-0 Processing EvidenceId: Rule2-Result-0 FACT Result=True 增長證據執行列表: Result End Processing Execution List: F1, Result, True, F2, False Processing EvidenceId: F1 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: F2, False, Result, True, Rule1 Processing EvidenceId: F2 加入鏈式的相關事實到執行列表: Rule1 End Processing Execution List: False, Result, True, Rule1 Processing EvidenceId: False End Processing Execution List: Result, True, Rule1 Processing EvidenceId: Result End Processing Execution List: True, Rule1 Processing EvidenceId: True End Processing Execution List: Rule1 Processing EvidenceId: Rule1 ExpressionEvaluator FACT F2 = 11 ExpressionEvaluator FACT F1 = 10 ExpressionEvaluator 11 > 10 = True ExpressionEvaluator NOT True = False End Processing End Iteration |
而後構造的XML文件的格式因爲 SRE的項目組的版本迭代,有一些根本沒法使用。上面的那個是通過調試後可用的。
須要注意的構造部分:
1. <Rule id="Rule1" desc="" chainable="True">
<Condition><![CDATA[ NOT(F2>F1) ]]></Condition>
<Actions Result="True">
<Evaluate factId="F2"><![CDATA[ F2+1 ]]></Evaluate>
<Execute factId="Rule2" />
</Actions>
</Rule>
也能夠 <Evaluate factId="Result"><![CDATA[ True ]]></Evaluate>
條件、行爲的真假、計算的事實、執行的事實
2.<Fact id="F1" desc="1" type="double" modelId="bob">
<xpath><![CDATA[ a/number1 ]]></xpath>
</Fact>
<xpath> 綁定 A標籤下number1的值 到 F1。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
條件若是是假的
<Rule id="Rule2" desc="">
<Condition><![CDATA[ 1!=1 ]]></Condition>
<Actions result="True">
<Evaluate factId="Result"><![CDATA[ True ]]></Evaluate>
<Evaluate factId="Result" result="false"><![CDATA[ False ]]></Evaluate>
</Actions>
</Rule>
<Fact id="Result" desc="Result" type="boolean" modelId="bob">
<xpath><![CDATA[ a/result2 ]]></xpath>
</Fact>
Execution List: Rule2
Processing
EvidenceId: Rule2
ExpressionEvaluator 1 != 1 = False
增長證據執行列表: Rule2-Result-1
End Processing
Execution List: Rule2-Result-1
Processing
EvidenceId: Rule2-Result-1
FACT Result=False
增長證據執行列表: Result
End Processing
進一步體現
<?xml version="1.0" encoding="utf-8" ?> <RuleEngine> <Rules> <Rule id="Rule1" desc="" chainable="True"> <Condition><![CDATA[ NOT(F2>F1) ]]></Condition> <Actions> <Evaluate factId="F2"><![CDATA[ F2+1 ]]></Evaluate> <Execute factId="Rule2" /> </Actions> </Rule> <Rule id="Rule2" desc=""> <Condition><![CDATA[ 1!=1 ]]></Condition> <Actions result="True"> <Evaluate factId="Result"><![CDATA[ True ]]></Evaluate> <Evaluate factId="Result" result="false"><![CDATA[ False ]]></Evaluate> </Actions> </Rule> <Rule id="Rule3" desc="" chainable="True"> <Condition><![CDATA[ 1==1 ]]></Condition> <Actions > <Evaluate factId="Result" ><![CDATA[ False ]]></Evaluate> </Actions> </Rule> <Rule id="Rule4" desc="" chainable="True"> <Condition><![CDATA[ 1==1 ]]></Condition> <Actions > <Execute factId="Rule2" /> </Actions> </Rule> </Rules> <Facts> <Fact id="F1" desc="1" type="double" modelId="bob"> <xpath><![CDATA[ a/number1 ]]></xpath> </Fact> <Fact id="F2" desc="2" type="double" modelId="bob"> <xpath><![CDATA[ a/number2 ]]></xpath> </Fact> <Fact id="True" desc="True" type="boolean" modelId="bob"> <xpath><![CDATA[ boolean(1) ]]></xpath> </Fact> <Fact id="False" desc="False" type="boolean" modelId="bob"> <xpath><![CDATA[ boolean(0) ]]></xpath> </Fact> <Fact id="Result" desc="Result" type="boolean" modelId="bob"> <xpath><![CDATA[ a/result2 ]]></xpath> </Fact> </Facts> </RuleEngine> |
這樣循環的推理 知道F2>10時纔可以推出 規則2,規則2成立時推理什麼,規則2不成立時推理什麼。
——————————————————————————————————————————————————
public override string[] ClauseEvidence
{
get
{
List<string> list = new List<string>();
foreach (EvidenceSpecifier es in actions)
{ //加載時也根據base.Value IsEvaluatable=true時影響設置。 而表達式的真實性設置一致時才能夠。
if ((bool)base.Value == es.truthality)//表達式爲真,規則爲假時,則沒有觸發
list.Add(es.evidenceID);
}
return list.ToArray();
}
}
規則類,在每次計算完成以後對其的actions 即 執行語句Evaluate 和excute 的到設置的值,
而後用當前的條件表達式值base.Value比較, 若是一致則把此actions 加入到應該調用的LIST中。
當條件表達式的值爲false時, 若是執行語句都是條件爲真才執行,那麼LIST中就沒有任何actions。也就是此規
則條件並不會執行任何語句。
evidence.Changed += delegate(object sender, ChangedArgs args)
{
IEvidence evidence1 = (IEvidence)sender;
if (!(evidence1 is IFact))
return;
//找出這ifact模型
IFact fact = (IFact)evidence1;
IEvidenceValue value = (IEvidenceValue)fact.ValueObject;
string modelId = value.ModelId;
//遍歷全部ifacts並添加這些到相同的模型來執行列表
foreach(IEvidence evidence2 in evidenceCollection.Values)
{
//排除全部不IFact證據類型
if (!(evidence2 is IFact))
continue;
//排除本身
if (evidence2.ID == evidence1.ID)
continue;
//排除全部那些不一樣的ifacts模型
if (evidence2.ValueObject.ModelId != modelId)
continue;
//加入list
executionList.Add(evidence2);
}
};
//除了其自身以外的事實,同一個MODELID下面的所有事實加載。 由於其自己就業務引擎,推理時的事實集中於一個事實集中去搜索。
//而個人事實要所有加載,就好像個人所有事實有且僅有一個事實集modelid同樣。
EvidenceValue類中的
public class Naked : IEvidenceValue//繼承自IEvidenceValue,實現接口的定義 屬性和方法。
public class Xml : IEvidenceValue
XML是事實值對象。FACT的內容和更改的事件綁定。
Naked是規則的值對象。Rules的內容和更改值事件的綁定。
Compiler.cs 是XML數據的加載,能夠返回ROM對象。
public static ROM Compile(XmlDocument document)
加載(規則,事實,表達式,事實與被規則做爲條件表達式的引用)。
ROM對象的方法---核心推理Evaluate
/// <summary>
/// 求值
/// </summary>
public void Evaluate()
{
//決策
Decisions.Decision decision = (new Decisions.Decision());
decision.EvidenceLookup += evidence_EvidenceLookup;
decision.ModelLookup += evidence_ModelLookup;
decision.Evaluate(evidenceCollection, dependentEvidence);
}
Decisions類--決策類
/// <summary> /// /// </summary> /// <param name="evidenceCollection"></param> /// <param name="factRelationships"></param> public void Evaluate(Dictionary<string, IEvidence> evidenceCollection, Dictionary<string, List<string>> factRelationships) { #region register all evidences in this rom with this instance of decision foreach (IEvidence evidence in evidenceCollection.Values) { evidence.CallbackLookup += RaiseCallback; evidence.EvidenceLookup += RaiseEvidenceLookup; evidence.ModelLookup += RaiseModelLookup; //除了其自身以外的事實,同一個MODELID下面的所有事實加載。 由於其自己就業務引擎,推理時的事實集中於一個事實集中去搜索。 //而個人事實要所有加載,就好像個人所有事實有且僅有一個事實集modelid同樣。 evidence.Changed += delegate(object sender, ChangedArgs args) { IEvidence evidence1 = (IEvidence)sender; if (!(evidence1 is IFact)) return; //找出這ifact模型 IFact fact = (IFact)evidence1; IEvidenceValue value = (IEvidenceValue)fact.ValueObject; string modelId = value.ModelId; //遍歷全部ifacts並添加這些到相同的模型來執行列表 foreach(IEvidence evidence2 in evidenceCollection.Values) { //排除全部不IFact證據類型 if (!(evidence2 is IFact)) continue; //排除本身 if (evidence2.ID == evidence1.ID) continue; //排除全部那些不一樣的ifacts模型 if (evidence2.ValueObject.ModelId != modelId) continue; //加入list executionList.Add(evidence2); } }; } #endregion #region load up the execution list with facts //加載執行列表與事實 foreach (IEvidence fact in evidenceCollection.Values) { if (!(fact is IFact)) continue; executionList.Add(fact); Debug.WriteLine("Added fact to execution list: " + fact.ID); } #endregion #region load up the execution list with chainable rules //加載執行列表鏈式規則 foreach (IEvidence rule in evidenceCollection.Values) { if (rule is IRule && ((IRule)rule).isChainable) { executionList.Add(rule); Debug.WriteLine("Added rule to execution list: " + rule.ID); } } #endregion #region execute list //執行列 //Debug.WriteLine("Iteration"); //Debug.IndentLevel++; while (executionList.HasNext) { Trace.WriteLine("Execution List: " + executionList.ToString()); Trace.WriteLine("Processing"); //Debug.IndentLevel++; //最低優先級做爲計算List第一項。 string evidenceId = executionList.Read(); IEvidence evidence = evidenceCollection[evidenceId]; Trace.WriteLine("EvidenceId: " + evidence.ID); //計算證實 evidence.Evaluate(); //若是證實有子句的,增長它的行爲 if (evidence.ClauseEvidence!=null) { foreach (string clauseEvidenceId in evidence.ClauseEvidence) { Evidence.IEvidence clauseEvidence = (Evidence.IEvidence)evidenceCollection[clauseEvidenceId]; executionList.Add(clauseEvidence); Trace.WriteLine("增長證據執行列表: " + clauseEvidence.ID); } } //執行列表的鏈式的相關的事實 if (factRelationships.ContainsKey(evidence.ID)) { List<string> dependentFacts = factRelationships[evidence.ID]; foreach (string dependentFact in dependentFacts) { Evidence.IEvidence dependentEvidence = (Evidence.IEvidence)evidenceCollection[dependentFact]; executionList.Add(dependentEvidence); Trace.WriteLine("加入鏈式的相關事實到執行列表: " + dependentEvidence.ID); } } //Debug.IndentLevel--; Trace.WriteLine("End Processing"); Trace.WriteLine(""); } //Debug.IndentLevel--; Trace.WriteLine("End Iteration"); #endregion } |
1.註冊所有的事實對象,並綁定事件方法(同一組事實狀態或值改變,則同一組其餘事實所有從新加載,再次計算時,看是否對其餘事實有新的狀態或者值改變的推理----每次有改動就所有加載)。
2.把事實與規則(用於首次處理的多個第一層次規則)加載進來。executionList 放入到當前執行列表中
3.爲何不加載actions行爲表達式,不是存放了嗎? 行爲表達式要規則的條件符合條件以後再存入當前執行列表中。
4.推理
這個推理很是好玩。充分體現了其程序架構的調用。
while (executionList.HasNext)
{
Trace.WriteLine("Execution List: " + executionList.ToString());
Trace.WriteLine("Processing");
//Debug.IndentLevel++;
//最低優先級做爲計算List第一項。
string evidenceId = executionList.Read();
IEvidence evidence = evidenceCollection[evidenceId];
Trace.WriteLine("EvidenceId: " + evidence.ID);
//計算證實
evidence.Evaluate();
//若是證實有子句的,增長它的行爲
if (evidence.ClauseEvidence!=null)
{
foreach (string clauseEvidenceId in evidence.ClauseEvidence)
{
Evidence.IEvidence clauseEvidence = (Evidence.IEvidence)evidenceCollection[clauseEvidenceId];
executionList.Add(clauseEvidence);
Trace.WriteLine("增長證據執行列表: " + clauseEvidence.ID);
}
}
//執行列表的鏈式的相關的事實
if (factRelationships.ContainsKey(evidence.ID))
{
List<string> dependentFacts = factRelationships[evidence.ID];
foreach (string dependentFact in dependentFacts)
{
Evidence.IEvidence dependentEvidence = (Evidence.IEvidence)evidenceCollection[dependentFact];
executionList.Add(dependentEvidence);
Trace.WriteLine("加入鏈式的相關事實到執行列表: " + dependentEvidence.ID);
}
}
//Debug.IndentLevel--;
Trace.WriteLine("End Processing");
Trace.WriteLine("");
}
對執行列表進行循環,知道執行列表中爲空結束。而在推理過程當中,不斷的把要處理的寫入執行列表。把處理完的移除執行列表。
string evidenceId = executionList.Read(); 讀取並移除列表。
IEvidence evidence = evidenceCollection[evidenceId]; 獲得當前對象(事實、規則、或者推理後加載進來的 actions 行爲表達式)
//計算證實
evidence.Evaluate();
按照程序的思路。 每次處理後都會利用change事件 對當前的執行列表LIST內的數據進行排序。會把事實排在前面。
1.1Fact
public override void Evaluate()
{
if (IsEvaluatable)
EvidenceValue.Evaluate();
}
由於fact的EvidenceValue是XML對象,執行XML的方法。
/// <summary>
/// 計算
/// </summary>
public void Evaluate()
{
XmlNode model = null;
model = ModelLookup(this, new ModelLookupArgs(modelId));
object x = getValue(model);
if (x == null)
throw new Exception("no value for fact");
if (previousValue==null || !x.Equals(previousValue))
{
previousValue = x;
Changed(this, new ChangedModelArgs(modelId));
}
}
設置到previousValue變量中。
XML的值
public object Value
{
get
{
return previousValue;
}
set
{
//若是傳入的值是之前的咱們沒處理的值if the incoming value is the previous value we have nothing to do
if (previousValue != value)
{
XmlNode model = null;
model = ModelLookup(this, new ModelLookupArgs(modelId));
setValue(model, value);
previousValue = value;
Changed(this, new ChangedModelArgs(modelId));
}
}
}
Changed調用時就致使同一組事實所有加入執行列表。
1.2規則Rule
public override void Evaluate()
{
ExpressionEvaluator e = new ExpressionEvaluator();
e.GetEvidence += new EvidenceLookupHandler(RaiseEvidenceLookup);
e.Postfix = this.postfixExpression;
ExpressionEvaluator.Symbol o = e.Evaluate();
base.EvidenceValue.Reset(); //清空以前的值
//結果是IEvidenceValue類型,或者表達式爲無效的,則拋出異常
IEvidenceValue result = o.value as IEvidenceValue;
//空返回退出
if (o.type == ExpressionEvaluator.Type.Invalid)
{
return;
}
//值被改變了則調用事件
if (base.Value.Equals(result.Value))
return;
base.Value = result.Value;//此方法,引起false時規則條件表達式中的引用爲0
RaiseChanged(this, new ChangedArgs());
}
聲明表達式對象, 把條件表達式拿來作中綴切割和中綴轉後綴。而後把nake對象清空。
條件表達式計算結果是個Symbol標誌對象。 此對象有個value屬性是Nake類型。
public struct Symbol// 象徵;符號;標誌
{
public string name;
public IEvidenceValue value;
public Type type;
public override string ToString()
{
return name;
}
}
因而Symbol.value是NAke。 Nake.value是值 真假。
Symbol.value.value 就存儲在rule類對象的value中。做爲當前規則對象的條件表達式是否成立的標誌。OK。 evidence.Evaluate();方法分析完成。
---------
下面進入Decision evidence.Evaluate(); 語句以後的其餘推理部分
當事實和規則推理完成後,
咱們會看這個事實和規則是否引起了什麼行爲, 事實通常沒有什麼行爲,都是規則,
//若是證實有子句的,增長它的行爲
if (evidence.ClauseEvidence!=null)
即:rules類的actions子句,
上面在 public override string[] ClauseEvidence 規則的 行爲屬性上有定義。
若是當前base.value 也就是 規則的條件表達式的值,真假與 行爲的真假要求不相同則不加入。
當都不相同是,即條件表達式爲假,且不符合行爲要求時, 那麼就沒有子句。
也就不須要再次進行計算其子句內容。
若是有子句。 例如 規則條件是真, 子句要求在條件是真的狀況下作操做。 那麼
此此子句執行
//若是證實有子句的,增長它的行爲
if (evidence.ClauseEvidence!=null)
{
foreach (string clauseEvidenceId in evidence.ClauseEvidence)
{
Evidence.IEvidence clauseEvidence = (Evidence.IEvidence)evidenceCollection[clauseEvidenceId];
executionList.Add(clauseEvidence);
Trace.WriteLine("增長證據執行列表: " + clauseEvidence.ID);
}
}
把本身加入到執行列表中。
若是是事實, //執行列表的鏈式的相關的事實
if (factRelationships.ContainsKey(evidence.ID))
且此事實是其餘規則的條件表達式的引用時,則此事實存入規則列表。
這裏是爲了規則執行時能找到想要的事實的值,而且在規則的執行會致使此事實的改變。
誰也不知道此事實的改變會不會引發 其餘事實值的變化 和其餘規則的引用計算。
甚至已經用此事實計算過了的規則,由於此事實的加載,會再次處理。 這就是爲何能夠經過
xml定義作到 1---10的遞增循環了。
//執行列表的鏈式的相關的事實
if (factRelationships.ContainsKey(evidence.ID))
{
List<string> dependentFacts = factRelationships[evidence.ID];
foreach (string dependentFact in dependentFacts)
{
Evidence.IEvidence dependentEvidence = (Evidence.IEvidence)evidenceCollection[dependentFact];
executionList.Add(dependentEvidence);
Trace.WriteLine("加入鏈式的相關事實到執行列表: " + dependentEvidence.ID);
}
}
本人聲明:沐海(http://my.oschina.net/mahaisong) 以上文章是通過本人設計實踐和閱讀其餘文檔得出。若是須要探討或指教能夠留言!歡迎