【问题标题】:Boolean logic rule evaluator布尔逻辑规则评估器
【发布时间】:2008-10-29 17:56:03
【问题描述】:

我基本上展示了一项调查,人们回答问题的方式很像测试, 并且有不同的路径,到目前为止它很容易,但我想让它更加动态,这样我就可以有一个通用规则,用于所有路径的测试,使评估器更容易使用目前我只允许 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 专业的。

【问题讨论】:

    标签: c# xml logic boolean rule-engine


    【解决方案1】:

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

    在你的能力范围内,你可以:

    • 一个 RuleBase 类,具有“公共抽象 bool Evaluate()”方法
    • TrueRule、FalseRule 和 OrRule 类,其中包含 RuleBase 对象列表
    • 一个 QuestionRule 类,它引用一个特定的问题

    您将按如下方式对其中的每一个实施 Evaluate 方法:

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

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

    【讨论】:

      【解决方案2】:

      如果您使用支持推理的适当规则引擎,它将更加高效和可扩展。

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

      【讨论】:

      • 您可以通过一些代码示例进行详细说明。
      【解决方案3】:

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

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

      与上面相同,只是它为您提供了错误的 ID: /rule[@id="1"]/false//@ID

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

      祝你好运

      【讨论】:

        【解决方案4】:

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

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

        <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;
        }
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-22
          • 2012-01-18
          • 2011-01-28
          • 2020-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多