从网上下载最新版的 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(); }
|
![](http://static.oschina.net/uploads/space/2013/0709/144235_3w0T_1014361.png)
分为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) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎