布尔逻辑规则评估程序

时间:2008-10-29 17:56:03

标签: c# xml logic boolean rule-engine

我基本上展示了一项调查,人们回答的问题很像测试, 并且有不同的路径,到目前为止很容易,但我想让它更具动态性,这样我就可以有一个通用规则用于测试所有路径,使评估器更容易使用当前我只允许AND,并且每个OR基本上成为集合中的另一个规则,

QuestionID,然后我形成了一堆AND规则

<rule id="1">
<true>
 <question ID=123>
 <question ID=124>
</true>
<false>
 <question ID=127>
 <question ID=128>
</false>
</rule>
<rule id="2"><true>
 <question ID=123>
 <question ID=125>
</true>
<false>
 <question ID=127>
</false>
</rule>

这条规则1说如果问题123和124得到回答是真的,而127,128是错误的,那么它们就会通过。 OR(规则2)如果123和125为真且127为假,它们也会通过。 如果有很多组合,这会变得乏味,所以我想在逻辑中实现OR,我只是不确定这个问题的最佳方法是什么。

我认为规则引擎过于复杂,必须有一种更简单的方法,也许是在LINQ中构建一个图形,然后评估它们是否通过,

谢谢!

- 不是compsci专业。

4 个答案:

答案 0 :(得分:2)

这不必复杂:你已经完成了大部分工作,因为你和元素有效地实现了一个AND类型规则。我将介绍一个可以容纳元素的元素。

在你的能力中,你可以拥有:

  • RuleBase类,带有“public abstract bool Evaluate()”方法
  • TrueRule,FalseRule和OrRule类,包含RuleBase对象列表
  • QuestionRule类,引用特定问题

您可以按如下方式对每个方法实施Evaluate方法:

  • TrueRule:仅当所有包含的规则从Evaluate返回true时返回true
  • FalseRule:仅当所有包含的规则从Evaluate返回false时才返回
  • OrRule:如果至少有一条包含的规则从Evaluate返回true,则返回true
  • QuestionRule:会返回原始问题的答案

此类层次结构实现了一个简单的抽象语法树(AST)。 LINQ,以System.Expressions.Expression类的形式,做了几乎相同的事情,但如果不清楚一切是如何组合的话,编写自己的LINQ会很有帮助。

答案 1 :(得分:1)

如果您使用支持推理的适当规则引擎,那么它将更有效且可扩展。

查看http://www.flexrule.com这是一个灵活,可扩展的规则引擎,支持三种类型的规则。程序,推理和规则流规则可以从您的应用程序外部化,并使用此框架执行。

答案 2 :(得分:0)

我不确定我是否完全理解您要解决的问题,但您可以使用简单的XPath来获取ID:

这将为您提供规则ID = 1的所有“真实”ID: /规则[@ ID = “1”] /真// @ ID

与上面相同,它只给你错误的ID: /规则[@ ID = “1”] /假// @ ID

最后是指向.NET中XPath简介的链接 http://www.developer.com/xml/article.php/3383961

祝你好运

答案 3 :(得分:0)

我建议将答案放在问题上,而不是使用truefalse对问题进行分组。我认为它使XML更容易阅读,这是有争议的。没有争议的是,它可以独立评估question元素,即无需了解您正在尝试评估它的上下文。这样可以实现更简单的代码。

我还从XML Schema中获取一个页面,并将OR逻辑实现为choice元素。如果任何子元素为真,则choice元素为true。当然,你可以嵌套它们:

<rule id="1">
   <question id="123" answer="true" />
   <question id="124" answer="false" />
   <choice id="1">
      <question id="125" answer='true' />
      <choice id="2">
         <question id="126" answer='false' />
         <question id="127" answer='false' />
      </choice>
   </choice>
</rule>

这将为您提供四种非常简单的实现方法,每种方法都使用前面的方法:

  • bool GetProvidedAnswer(int questionID)
  • bool IsQuestionCorrect(XmlElement question)
  • bool IsChoiceCorrect(XmlElement choice)
  • bool IsRuleSatisfied(XmlElement rule)

XML的结构使这些方法实现起来非常简单:

 bool IsRuleSatisfied(XmlElement rule)
 {
    bool satisfied = true;
    foreach (XmlElement child in rule.SelectNodes("*"))
    {
       if (child.Name == "question")
       {
          satisfied = satisfied && IsQuestionCorrect(child);
       }
       if (child.Name == "choice")
       {
          satisfed = satisfied && IsChoiceCorrect(child);
       }
       if (!satisfied)
       {
          return false;
       }
   }
   return true;
}

可能值得在List<XmlElement>方法的参数中添加IsFooCorrect。 (如果规则引擎在一个类中,你可以使它成为一个类字段。)当一个答案错误时,让所有方法将当前元素添加到列表中。然后,您可以检查该列表的内容,以确切了解规则失败的原因。