[英]Boolean logic rule evaluator
我基本上有一个显示的调查,人们回答问题很像测试,并且有不同的路径,到目前为止很容易,但我想让它更具动态性,以便我可以有一个通用规则用于所有路径的测试,为了使评估器更容易使用,目前我只允许 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专业。
这并不一定很复杂:您已经完成了大部分工作,因为您的 and 元素有效地实现了 AND 类型规则。 我将介绍一个可以容纳和元素的元素。
在你可以,你可以:
您将按如下方式对其中的每一个实现 Evaluate 方法:
此类层次结构实现了一个简单的抽象语法树 (AST)。 LINQ,以 System.Expressions.Expression 类的形式,几乎可以做同样的事情,但是如果所有东西如何组合在一起并不明显,那么编写自己的代码会很有帮助。
如果您使用支持推理的适当规则引擎,它将更加高效和可扩展。
看看http://www.flexrule.com ,它是一个灵活的、可扩展的规则引擎,支持三种类型的规则。 程序、推理和规则流规则可以从您的应用程序中具体化,并使用此框架执行。
我不确定我是否完全理解您要解决的问题,但您可以使用简单的 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
祝你好运
我建议把对问题的答案,而不是用true
和false
,以组提出的问题。 我认为它使 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;
}
可能值得将List<XmlElement>
添加到IsFooCorrect
方法的参数。 (如果规则引擎在一个类中,您可以将其设为类字段。)当答案错误时,所有方法都将当前元素添加到列表中。 然后,您可以检查该列表的内容以确切了解规则失败的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.