Drools Core DRL - 只有一个具有最高显着性的规则,跳过其他规则

时间:2014-03-17 20:01:08

标签: java drools rule

我有简单的JAVA bean,有两个int字段:' a'和' b'。

我有两条规则:

rule "First rule"
salience 10
when
    $bean : Bean ( a == 1)
then
    $bean.setB(10);
end

rule "Second rule"
salience 20
when
    $bean : Bean ( a == 1)
then
    $bean.setB(20);
end

实际结果:"第二条规则"首先被解雇(更高的突出性),"第一个规则"被解雇了。

预期结果:只触发一条规则(具有最高显着性)。其他规则被忽略。这该怎么做? Drools有可能吗?我正在使用Drools 6.0.0 Final。

要求: 1.我无法使用激活组'。 我不想使用'撤回'在每个豆子上。

更新

非常感谢您的回答。

可能我应该详细描述我的问题。 我有一套1500条规则。每条规则:

  • 使用相同的bean - 这个bean有很多字段(属性),
  • 有显着性,
  • 有很多条件,
  • 只有一个动作 - 在我的bean中设置一个(总是相同的)布尔标志。

我想要的是什么? 当我遇到冲突时(输入事实由两个或更多规则匹配)我想只触发一个具有最高显着性的规则。应该忽略针对这一事实的其他匹配规则。最重要的是性能 - 这应该尽可能快。

我做了什么? 目前我有两个解决方案,但我不知道哪一个更好,或者我应该以不同的方式解决这个问题。

解决方案1 ​​ - 有状态会话

Java代码:

for (Object fact : facts) {
    FactHandle fh = session.insert(fact);
    session.fireAllRules(1);
    session.delete(fh);
}

解决方案2 - 无状态会话

Java代码:

for (Object fact : facts) {
    session.execute(fact);
}

解决方案2的DRL文件: 我在每个规则中添加了相同的激活组:

rule "Rule"
activation-group "group"
salience X
when
    ...
then
    ...

5 个答案:

答案 0 :(得分:4)

基于你的问题,我担心你可能会误解突出点。突出性是优先级值。 Drools使用它来确定在满足多个规则的约束的情况下首先开始流口水。

在某些情况下解雇规则P并且在规则P被解雇时不规则Q的问题是常见问题。您的对象模型应该设置为这是推理概念空间的自然结果。对于您列出的字面情况,您可以尝试将新事实插入工作内存(“RuleFiredFact”,其值为“2nd”或其他)。然后,您将在第一个规则约束中检查此事实。如果是,则第一条规则不会触发。

<强>更新 需要说明的是,“RuleFiredFact”是一个抽象占位符,用于表示事实模型中的某些具体事实。流氓的一部分不是在drools DSL中使用抽象的东西。

<强>更新

状态与无状态会话是否合适将取决于您可用的计算机资源,对象模型,团队,列表还在继续。如果您不知道使用哪个,则应参考有关该主题的讨论。您可以尝试使用此旧邮件列表http://drools.46999.n3.nabble.com/Advice-sought-on-choosing-Stateful-or-Stateless-sessions-td57069.html

无论你使用哪种方式,我都强烈怀疑你的对象模型太浅了。创建一个包含一个事实的drools系统是非常罕见的,然后再也不会创建。流口水的目的是推理一些事实。解决这个问题的方法可能就像移动你的对象并将其中的信息作为事实插入到drools工作内存中。然后,您将编写仅在您想要的约束下触发的规则。

在我所描述的情况下,有很多方法可以确保只有一条规则可以触发。您的规则可能都在寻找“factWasAlreadyReasonedOverFact”,并引用了触发执行的事实。这是一个非常粗略的例子。希望它能给你一个想法。

答案 1 :(得分:1)

首先让我告诉你,你有一些奇怪的场景:)

此问题有多种解决方案:

  • 使用Bean类的另一个属性来标记已经处理过的&#39;事实。
  • 使用自定义AgendaFilter
  • 使用ksession.fireAllRules(1);

希望它有所帮助,

答案 2 :(得分:1)

您可以使用drools.halt();在您的最高显着性规则中。

此操作是终止流程并退出规则执行(正是您所需要的)。

答案 3 :(得分:0)

我会使用 <Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}"> <Setter Property="Background" Value="White" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Margin" Value="5" /> <Setter Property="FontSize" Value="18" /> <Setter Property="Padding" Value="27" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RadioButton}"> <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border x:Name="radioButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="100" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="Center"> <Grid x:Name="markGrid" Margin="2"> <Ellipse x:Name="optionMark" Fill="#FF212121" MinWidth="6" MinHeight="6" Opacity="0"/> </Grid> </Border> <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasContent" Value="True"> <Setter Property="FocusVisualStyle"> <Setter.Value> <Style> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </Setter.Value> </Setter> <Setter Property="Padding" Value="4,-1,0,0"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFF3F9FF"/> <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FF5593FF"/> <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFE6E6E6"/> <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FFBCBCBC"/> <Setter Property="Fill" TargetName="optionMark" Value="#FF707070"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="radioButtonBorder" Value="#FFD9ECFF"/> <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="#FF3C77DD"/> <Setter Property="Fill" TargetName="optionMark" Value="#FF212121"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Opacity" TargetName="optionMark" Value="1"/> </Trigger> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter Property="Opacity" TargetName="optionMark" Value="0.56"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> activation-group解决此问题,如解决方案2中所述

答案 4 :(得分:0)

您可以尝试的一个解决方案是&#34;锁定活动&#34;属性以避免涉及一个或多个规则的无限执行循环。

锁定活动由规则组确定范围,并且只要该组被聚焦,就会阻止规则重新启动。它不依赖于新事实或对现有事实的更新,而只取决于议程重点。如果您不操纵组,这可能是一个选项。