Can i only have one agenda-group declaration for the same rule in Drools 6?
Can I put this?
rule "rule_x"
agenda-group "group_x"
agenda-group "group_y"
when
then
end
I want to active a this rule when several groups are focused.
Most rule attributes are just syntactic sugar, and agenda-group is one of them. It's easy to achieve the same effect by falling back to logic patterns.
Define
class Group { private String name; ... }
and use one instance of it as a fact to represent the currently active group. Rules will have to show an additional pattern:
rule in-group-one
when
Group( name == "one" )
...
If the rule to be in several groups at the same time:
rule in-groups-one-two
when
Group( name in ("one", "two") )
You can also mimic the behaviour of agenda group stacking.
Later
The idea of focussing more than one group at the same time should be considered very carefully. While it is clear that a rule in groups a, b and c should fire when these three groups are in focus, it isn't clear at all what should happen with a rule in groups a and b, or with another rule in groups a, c and d. Whatever should happe can indeed be expressed in logic, but does it make sense, and (more importantly) is it useful?
Related
I am having an issue understanding RETE algorithm Beta node JoinNode and notNode?
Documentation says :
There are two two-input nodes, JoinNode and NotNode, and both are
types of BetaNodes. BetaNodes are used to compare 2 objects, and their
fields, to each other. The objects may be the same or different types.
By convention, we refer to the two inputs as left and right. The left
input for a BetaNode is generally a list of objects; in Drools this is
a Tuple. The right input is a single object. Two Nodes can be used to
implement 'exists' checks. BetaNodes also have memory. The left input
is called the Beta Memory and remembers all incoming tuples. The right
input is called the Alpha Memory and remembers all incoming objects.
I understood, Alpha Node: Various literal conditions for drl rules but above documentation for BetaNodes is confusing me a bit.
say below is drl condition for above diagram:
$person : Person( favouriteCheese == $cheddar )
Query: 1) what are these left and right inputs to two-input Beta Nodes exactly as explained in above documentation? I believe it's referring to facts and rules where I believe tuples would be facts?
2) notNode would be basically drl condition matching literal condition with not?
Updated question on 6Sep17:
3) I believe above diagram represent joinNode, how would notNode be represented , if above workflow is altered to suit notNode?
The condition corresponding to the diagram would be
Cheese( $name: name == "Cheddar" )
Person( favouriteCheese == $name )
Once there is a match, a new tuple consisting of the matching Cheese and Person is composed and can act as a new tuple for further matches if there is a third pattern in the condition.
A not-node would be one that asserts the non-existence of some fact. It would fire only once.
You might find a much better description of "rete" on the web.
I need to write a rule in Drools 6.5 that checks for the existence of an event of type A. There is a second class named B which has a field date.
While checking for existence of an event A, if at least one event of type B exists, A must happen after the latest B.date in order for the rule to fire; otherwise the rule should fire regardless of any B events.
Both event types of A and B have their own explicit timestamp field.
when
// TODO if at least one event of type B exists, A must happen after max(b.date). Otherwise, the rule must fire regardless of any B
$a : A( ... )
then
...
How do I perform this check?
EDIT: If no B is present in the working memory, and A meets the requirements, the rule must fire regardless.
This will fire for each A meeting the temporal constraint that it should happen after all Bs.
$b: B()
not B(this after $b)
$a : A( this after $b )
If you want to fire this only once, for any number of As, use exists in front of A and omit the binding.
I'm wondering if there is anything in drools that can be used to determine how close a rule is (or has been) to being activated?
From all that I can tell, the standard drools doesn't support anything like it, I just wondered if I might have missed something.
I glanced at Drools Chance (https://github.com/droolsjbpm/drools-chance), but it seems that it hasn't been developed a lot anymore recently and doesn't seem ready for Drools 6.x.
I know that AgendaEventListeners can be used to intercept when a rule has fired but it doesn't look like there is anything to intercept if a single condition of a rule has been evaluated to true.
Am I missing something or is this a current limitation of drools to not have any support for this kind of thing?
Thanks!
Perhaps you could use a work around. Construct a set of extra rules that write metrics for when they fire depending on your definition of close--that could be 1..n parts of the LHS for the rule of interest and/or thresholds for nearness to any part of the LHS (say you want to know when a value approaches to with 90% of another value). For complex conditionals in source code (not Drools related), I've used approaches like the below to trace complicated and nested logic:
boolean a1 = property1 > property2
boolean a2 = (!isHigh || isMedium)
boolean a3 = property 4 == property5
System.out.println ("rule2: " + a1 + " " + a2 + " " + a3);
if (a1 && a2 && a3) {
...do something
}
This is related what I called "learning the reason for failure". Consider that you have to pass n qualifications. Rather than being told that you have failed you'd like to have a list of the "pass" (and "fail") criteria.
One rule evaluating all of this in a lump sum is no good. You have to write one rule for each of the n criteria and collect the positives with the fact holding the properties under survey. Finally, one low-priority rule can check whether you have all n ("hooray") and another one can tell you "sorry, no", but it can give you a list what succeeded (and what not).
Lots of effort, but good information is always costly.
I'm trying to use Drools backward chaining to find out which facts are needed to get an object inserted in the working memory.
In the following example, I expect to get the fact "go2".
rule "ins a"
when
String( this == "go2" )
then
insert(new A());
end
rule "Run"
when
then
insert(new String("go1"));
end
rule "Test isThereAnyA"
when
String( this == "go1" )
isThereAnyA(a;)
then
System.out.println( "you can get " + a );
end
query isThereAnyA (A a)
a := A()
end
I've been looking at examples in the official documentation
http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21289
but they show a different situation (the rules in those examples doesn't creates new fact)
From the chart
http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21240
I think it should work but I haven't found a way to specify a query that gives me the expected results.
Thank you in advance.
Short answer:
Unfortunately backward chaining can not be used for this purpose.
It will not give you "go2" in this case.
Long answer:
In Drools, Backward chaining (BC) is a way to query the WM in a goal-driven fashion, not a way to trace back the derivation graph of a normal forward chaining inference process.
BC allows rule "Test" to retrieve As through the query "isThereAnyA", and possibly invoke other queries, but will not allow to find the "production" link between "A" and "go2". The reason is that "when..then..insert.." does not create any link between the triggering facts and the asserted conclusion, and backward chaining will not change it.
What you could do with BC is this:
query isThereAnyA_InPresenceOfA_String( A a )
isThereAnyString( $s ; )
a := A()
end
query isThereAnyString( String $s )
$s := String( this == "go2" )
end
This will pick up As only if a String "go2" is (still) present. However you'll notice that the connection between a particular instance of A and a the particular String which led to its assertion is still missing.
To know exactly which objects led to the assertion of another object you may need a different approach. Options include:
make the connection explicit : new A( $s ) // $s bound to "go2"
use "insertLogical" to establish a dependency between "go2" and A, then query the TruthMaintenanceSystem
The TMS-based one would be my tentative choice, but it also depends on your exact requirements.
This use case is common, there may be other options, including a few which are experimental as they are being developed in 6.3, but I'd rather ask a few questions first.
That is: when do you need exactly to discover the facts - during the execution of the rules, or "offline"? Is it purely for auditing purposes, or does it impact your business logic? Can you have multiple rules asserting the "same" object?
Hope this helps
Davide
The most basic use of from clause is not working, even when I know there are elements in the list and there is no conditions for the elements being extracted from that list, and I have other rules working properly.
Here is what happens, there are many variables in my problem, but I have simplified to this:
Having this two rules, the firstone is made to demostrate that fixedShipmentValueData list, has at least one element. However, the second rule isn't fired, even when the only different thing it does from the firstone, is to use the from clause and put a variable name.
rule "Print list value"
ruleflow-group "fixed-values"
no-loop
when
cParams: CustomerParameters(list: fixedShipmentValueData)
then
System.out.format("There are %s elements at fixedShipmentValue and fixed value is %s%n",list.size(),
((ParameterValues)list.get(0)).getFixedShipmentValue());
end
rule "Do something with the list"
ruleflow-group "fixed-values"
no-loop
when
cParams: CustomerParameters(list: fixedShipmentValueData)
ParameterValues($fixedShipmentValue: fixedShipmentValue) from list
then
System.out.format("fixed Shipment Value is %s%n", $fixedShipmentValue);
end
This looks so simple... I have expent enough time as to be out of ideas.
Without seeing the Java code for CustomerParameters, ParameterValues and the application part that creates, composes and inserts the fact(s) there's just one scenario I know that can reproduce the effect as you have told it. Consider this:
A List<Base> is field list in class X. There are subclasses SubA and SubB both extending Base. Create X, add objects of class SubA to list. A rule (like "Print list value") will show that the list is not empty.
However, a rule using a pattern such as
X( $list: list )
SubB() from $list
will never fire, since there are no SubB's in Base.list.