Rule Fires with Null Bindings
by mark.nowicki
Hi, I'm getting duplicate rule invocations when a rule is added to the
KnowledgeBase after the facts have been inserted in the
StatefulKnowledgeSession. Very simple example, seems what I'm doing is
consistent with 5.3.0.Final Drools expert documentation. Thanks for the
assistance,
--Mark
*Running code below outputs the following (firing twice for Person A,
Relationship A-C):*
RelationshipRule Fired!
person: Person( id=A, type=parent )
relationship: Relationship( parentId=A, childId=C )
RelationshipRule Fired!
person: Person( id=A, type=parent )
relationship: Relationship( parentId=A, childId=B )
RelationshipRule Fired!
person: Person( id=A, type=parent )
relationship: Relationship( parentId=A, childId=C )
*resources/factTypes.drl:*
package testing.facttypes;
declare Person
id : String
type : String
end
declare Relationship
parentId : String
childId : String
end
*resources/rules.drl:*
package testing.rules;
import java.util.ArrayList;
import testing.facttypes.Person;
import testing.facttypes.Relationship;
rule "RelationshipRule"
no-loop true
when
person : Person(type == "parent")
relationship : Relationship(parentId == person.id)
then
System.out.println("RelationshipRule Fired!");
System.out.println("person: " + person);
System.out.println("relationship: " + relationship + "\n");
end
*public static void main snippet:*
KnowledgeBase knowledgeBase =
KnowledgeBaseFactory.newKnowledgeBase();
StatefulKnowledgeSession statefulKnowledgeSession =
knowledgeBase.newStatefulKnowledgeSession();
KnowledgeBuilder knowledgeBuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder(knowledgeBase);
Resource factTypes =
ResourceFactory.newClassPathResource("resources/factTypes.drl");
knowledgeBuilder.add(factTypes, ResourceType.DRL);
knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
FactType factType =
knowledgeBase.getFactType("testing.facttypes", "Person");
Object personA = factType.newInstance();
factType.set(personA, "id", "A");
factType.set(personA, "type", "parent");
statefulKnowledgeSession.insert(personA);
factType = knowledgeBase.getFactType("testing.facttypes",
"Person");
Object personB = factType.newInstance();
factType.set(personB, "id", "B");
factType.set(personB, "type", "child");
statefulKnowledgeSession.insert(personB);
factType = knowledgeBase.getFactType("testing.facttypes",
"Relationship");
Object relationshipAB = factType.newInstance();
factType.set(relationshipAB, "parentId", "A");
factType.set(relationshipAB, "childId", "B");
statefulKnowledgeSession.insert(relationshipAB);
factType = knowledgeBase.getFactType("testing.facttypes",
"Person");
Object personC = factType.newInstance();
factType.set(personC, "id", "C");
factType.set(personC, "type", "child");
statefulKnowledgeSession.insert(personC);
factType = knowledgeBase.getFactType("testing.facttypes",
"Relationship");
Object relationshipAC = factType.newInstance();
factType.set(relationshipAC, "parentId", "A");
factType.set(relationshipAC, "childId", "C");
statefulKnowledgeSession.insert(relationshipAC);
knowledgeBuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder(knowledgeBase);
Resource rules =
ResourceFactory.newClassPathResource("resources/rules.drl");
knowledgeBuilder.add(rules, ResourceType.DRL);
knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
statefulKnowledgeSession.fireAllRules();
--
View this message in context: http://drools.46999.n3.nabble.com/Rule-Fires-with-Null-Bindings-tp4019021...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 8 months
Avoid caching method results within non fact objects
by rogelio_sevilla1
Good day everyone, I'm having a problem here and I'm not sure if I'm using
the right approach.
Currently I have a couple of rules where I inject A LOT of objects as facts.
These objects change their states quite commonly and I have to make
decisions when the previous state has a particular value comparing it to the
current state. Something like this (just an example, sorry if there are
typos)
rule "Interesting Event"
when
$currentFact: CurrentFact(state=="somethingNew")
$previousFact: PreviousFact($currentFact.id == id && state=="somethingOld")
then
//do something
//update previousFact to reflect the state of the newFact
end
The problem that I had with this is that I had SOOO much facts within the
rules session (thousands of objects with a lot of data that I need within
the session too) that the fireAllRules method started to take too much time
to complete.
So, what I did is to store the previous facts of the objects within a
Wrapper class that contains a hashmap with all of these states.
Something like:
PreviousStateHolder{
private static HashMap<String,PreviousFact> previousFacts;
public void insertPreviousState(){
...
}
public boolean containsPreviousState(CurrentState currentState){
...
}
public boolean deletePreviousState(){
...
}
.. other management methods
}
And my new rules look like
rule "Interesting Event"
when
$currentFact: CurrentFact(state=="somethingNew")
$previousFact: PreviousFact(state=="somethingOld")
from
PreviousStateHolder.retrievePreviousState($currentFact)
then
//do something
//update previousFact to reflect the state of the newFact
end
The problem is that drools caches the result returned by the
retrievePreviousState() method, so, it does not matter if the
PreviousStateHolder member changes; drools always caches the result. I have
tried to put my invocations within eval() but I still get the same problem
(cached results).
I know they are being cached because I put a breakpoint within the methods,
and the first time the fireAllRules gets executed, they get hit. But then,
the consequence of these rules keep getting executed even if the
retrievePreviousState() does not reflect the value needed to do so.
Am I doing something wrong?? Is there another approach that does not involve
inserting all of these states as facts within my session??
Thanks a lot in advance
--
View this message in context: http://drools.46999.n3.nabble.com/Avoid-caching-method-results-within-non...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 8 months
cross products in excel decision tables
by Tom Eugelink
I need to model something similar to "when the lastname on a passport does not match the lastname on the application" in a decision table. Written in DRL:
rule "PassportValidation_24"
when
$a : Application()
$p : Passport(application == $a, lastName != $a.lastName)
then
$p.setError("Passport's last name (" + $p.getLastName() + ") does not match with application's last name (" + $a.getLastName() + ")");
end
How do I do such a cross referencing in an Excel decision table?
Tom
13 years, 8 months
log4j has no logging, but setup according to documentation
by Tom Eugelink
I'm still pretty new to drools (5.4.0 final) and I would like to see what Drools does; rules validation, MVEL expression evaluation, etc.
There is a webpage that says that in order to activate logging I need to add a line to my log4j.xml:
/http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html_single/index.html#d0e2947
/
First remark is that the XML is old style log4j; the current XML uses loggers and levels instead of category and priority. Beside that, it does not seem to work. After I've added /<logger name="org.drools"><level value="debug" /></logger>/ to my xml, nothing is logged. I know for sure that log4j via slf4j is working:
/log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@1c672d0.
log4j: Using URL [file:/C:/Documents%20and%20Settings/User/My%20Documents/frozn/components/engine/_build/log4j.xml] for automatic log4j configuration.
...
2012-08-02 10:55:04,400 INFO nl.o837.frozn.engine.drools.test.DroolsExcelTrial.main(DroolsExcelTrial.java:49) running trail
...
/
However there is no Drools logging output on the console, only the print statements I've placed in the entity models. If I add this line to the code:
/KnowledgeRuntimeLoggerFactory.newConsoleLogger(sessionObject);/
Then there is some logging output:
/OBJECT ASSERTED value:nl.o837.frozn.bm.Application@f664ec&ApplicationId=1 factId: 1
ACTIVATION CREATED rule:PassportValidation_20 activationId:PassportValidation_20 [2] declarations: p=nl.o837.frozn.bm.Passport@5e29e5&PassportId=2(2)
OBJECT ASSERTED value:nl.o837.frozn.bm.Passport@5e29e5&PassportId=2 factId: 2
BEFORE ACTIVATION FIRED rule:PassportValidation_20 activationId:PassportValidation_20 [2] declarations: p=nl.o837.frozn.bm.Passport@5e29e5&PassportId=2(2)
/
So Drools actually is producing logging information.
Is the documentation on the webpage incorrect? How do I get the logging information I would like?
Tom
13 years, 8 months
fire a rule only once (for the time being)
by slyfox
It seems like there are many similar problems but I have not been able to
find anything that addresses my issue exactly.
I have a stock trading application, and I want to check if the price is out
of a range (high,low)
if the price goes below low, the problem is the rule keeps firing if the
price keeps going lower, this creates too much noise and overhead.
I thought maybe the no-loop and duration attributes would help but they
didnt.
I know I could check not(Fired()) and use insert fired but I believe that
spans the entire session which I do not want either.
Is there a way to say fire this rule if true once then wait a period of time
before I check again.
>From what Ive read maybe agenda filters, but I am not sure if that is
flexible enough.
--
View this message in context: http://drools.46999.n3.nabble.com/fire-a-rule-only-once-for-the-time-bein...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 8 months