gpt4 book ai didi

具有显着性问题的 Drools 冲突解决程序

转载 作者:行者123 更新时间:2023-12-02 00:34:59 38 4
gpt4 key购买 nike

我发现了 drools 引擎的奇怪行为。我有两个具有不同显着性的规则。如 drools 文档中所述

3.3.4.1. Conflict Resolution

Conflict resolution is required when there are multiple rules on the agenda. (The basics to this are covered in chapter "Quick Start".) As firing a rule may have side effects on the working memory, the rule engine needs to know in what order the rules should fire (for instance, firing ruleA may cause ruleB to be removed from the agenda).

The default conflict resolution strategies employed by Drools are: Salience and LIFO (last in, first out).

The most visible one is salience (or priority), in which case a user can specify that a certain rule has a higher priority (by giving it a higher number) than other rules. In that case, the rule with higher salience will be preferred. LIFO priorities are based on the assigned Working Memory Action counter value, with all rules created during the same action receiving the same value. The execution order of a set of firings with the same priority value is arbitrary.

但是执行我的两条规则,每种类型有 5 个对象会产生奇怪的结果 - 在某些对象上,显着性为 1 的规则比显着性为 10 的规则执行得早。如果我从规则中删除更新,首先执行显着性为 10 的规则,然后才执行显着性为 1 的规则。

 package com.sample

import com.sample.DroolsTest.Message;
import com.sample.DroolsTest.Message2;



rule "Hello World2"
salience 10
when
m : Message()
m2 : Message2(status <0)
then

System.out.println( "Second Rule With Salience 10");
System.out.println( "m status = "+m.getStatus());
System.out.println( "m2 status = "+m2.getStatus());
m2.setStatus(m2.getStatus()*(-1));
update(m2);
end

rule "Hello World3"
salience 1
when
m2 : Message2()
m : Message()
then
System.out.println( "Third Rule With Salience 1");
System.out.println( "m status = "+m.getStatus());
System.out.println( "m2 status = "+m2.getStatus());
end

rule "GoodBye"
salience 0
when
eval(true)
then
System.out.println( "End" );
end

这里是 java 代码,可以让你更快地测试它

    package com.sample;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

/**
* This is a sample class to launch a rule.
*/
public class DroolsTest {

public static final void main(String[] args) {
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// go !
System.out.println("Start");
for(int i=0; i<5; i++){
Message message = new Message(i);
ksession.insert(message);
Message2 message2 = new Message2(-i);
ksession.insert(message2);
}
ksession.fireAllRules();
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}

private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}

public static class Message {

private int status;

public int getStatus() {
return this.status;
}

public Message(int status) {
super();
this.status = status;
}

public void setStatus(int status) {
this.status = status;
}

}

public static class Message2 {

private int status;

public Message2(int status) {
this.status = status;
}

public int getStatus() {
return this.status;
}

public void setStatus(int status) {
this.status = status;
}

}

}

谢谢,非常感谢您的帮助。PS:我知道,依赖规则触发的顺序并不是一个好主意,但在我运行这个之前,显着性对我来说似乎是值得信赖的。

最佳答案

查看您的 drl 文件,您正在给出条件“何时”第 m2 部分:Message2(status <0),请记住,LHS 仅在断言时或在调用给定事实的 modify()/update() 时进行评估。因此,在断言时,条件将评估为真并激活规则。您永远不会在同一对象上调用修改()/更新。Message2,因此,您的条件永远不会重新评估。这就是为什么你会得到奇怪的行为。这就是为什么您无需更新即可获得所需行为的原因。

关于具有显着性问题的 Drools 冲突解决程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5029318/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com