《专家系统破解篇 九、Simple Rule Engine规则推理引擎一》

从网上下载最新版的 SRE也是06年的了。 而且代码中的测试用例和逻辑不搭边。通过仔细研究,做出一个靠谱的例子能够让系统跑起来,然后又可以提现程序功能的。

RuleExample.xml 文件

<?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>
      </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();
          

        }

          



分为3层来看。

1.接口Ievidence。

2.Aevidence 、 Ifact、IRules、IAction

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) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎

转载于:https://my.oschina.net/mahaisong/blog/143430

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值