《專家系統破解篇 9、Simple Rule Engine規則推理引擎一》

從網上下載最新版的 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



經過上面的例子能夠充分分析出來。此程序中的推理必須以 chainable = " True " 做爲非別人的子邏輯來加載。

而後構造的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) 以上文章是通過本人設計實踐和閱讀其餘文檔得出。若是須要探討或指教能夠留言!歡迎
相關文章
相關標籤/搜索