I have two rules, they have same salience,same LHS but different RHS. I want the two rule will be both executed. However, both of them will make the LHS pattern can not be matched again. If I use modify() or update(), there must be one of them can not be executed.
Is there some strategy that making the drools know that the working Memory has been changed after all RHS have been executed?
One could argue that having two rules with the same LHS is poor design. This is especially so if the RHS of one or the other intends to modify one or more of the participating facts.
So the first advice is: combine the right hand sides so that you have a single rule.
The next best would be to make the firing order deterministic. Use salience in both, so that their relative oder is guaranteed. Move all update/modify calls to the rule with lower salience.
Finally, there's no need to use update/modify if the changes need not be "seen" by the rule engine. This (what I call) "dirty update" is handy where information should be accumulated but does not have any influence on LHS logic.
Related
I have a Guided Rule file that sets a configuration for some convergence factors. Later I have a Guided Decision Table which has the same rule flow group.
Even when I don't mention any salience in both these files, the Guided Rule gets executed first and sets the configuration value, and the same model is later imported in the Guided Decision table and these default values are set in Guided rule are used in the Guided Decision table.
Is there a specific reason "why guided rules get execute first and guided decision tables gets executed later, even though they have the same rule flow group"
Unless you're using saliences, execution order is non-deterministic. There are no guarantees that Rule A will always go before Rule B. It might always go in this order (A -> B) right now, but that's not guaranteed, and tomorrow or the next time you do a rules change or a version update, it might go in a different order. It usually has to do with the order that rules are loaded into memory, (which is why un-salience'd rules in a single DRL file tend to be executed top of file to bottom of file, because that's the order they're read.)
If your rules are such that you require them to be executed in a specific order, you should put saliences on them so that Rule X will always execute before Rule Y because of the saliences on them. Alternatively, you could rewrite your rules to not rely on execution order (this is considered good practice anyway.)
The only order guarantee that Drools provides is that rules of a given salience will execute at the same time, though the order of those rules within the salience is not guaranteed. Rules with no salience are all defaulted to salience 0, so this guarantee holds true. All of the rules execute, but no order is guaranteed and cannot necessarily be consistently determined ahead of time (hence "non-deterministic.")
So really, at the end of the day, when your question is "which rule gets executed first?" the answer is -- unless you have saliences, it shouldn't matter. And if it does matter, you need to fix your rules.
We are working on a monitoring application in which we follow the processing of a task in a set of applications.
Each application task processing is designed as ChainStep, the whole task process is designed as Chain.
Chain contains a tree of ChainSteps, each ChainStep may be parent of others.
We have a set of drools rules matching our needs but we have some performance issues (we may have easily up to 50k objects in session).
We are looking for best practices to improve drools performances.
Currently we represent Chains and ChainSteps as flat objects, each object has Id (GUID), we frequently have rule with conditions such as:
rule "Chain_App1_LinkToParent"
when $app1Step:App1ChainStep(!HasParent )
$app2Step:App2ChainStep($app2Step.ChainId == $app1Step.ChainId)
then
modify($app1Step) {
setParent($app2Step.getId()),
setHasParent(true)
}
end
(App1ChainStep and App2ChainStep both extends ChainStep type)
We tried to use unification but rules processing seems slower
when $app1Step:App1ChainStep(!HasParent, $Id:=ChainId )
$app2Step:App2ChainStep($Id:=ChainId)
We are working now on a non flat representation, but we encounter problems on rules triggering on object modifications.
For example:
rule "SetChainCollectable"
when
$chain:Chain(!Collectable )
not ( exists( $chainStep:ChainStep( !Collectable) from $chain.Steps))
then
modify($chain){
setCollectable(true)
}
end
seems not triggered on ChainStep modification of Collectable flag.
We would like to sure to obtain a better result before to finnish to migrate our rules.
What would be the more efficient way to represent object tree in Drools ?
For designing an efficient fact representation all use cases and their frequencies must be taken into account. (What you've let out in your question is far from the mark.) So I can only point out a few oddities I've observed:
Maintaining a parent and a hasParent could be simplified. Most of the time, IDs have a null value, NULL or 0 etc. Perhaps you should object references rather than ID values.
Unification isn't useful for the rule pattern you have there.
not( exists() ) is redundant - not() is the negative existence quantifier all by itself. (Drools discards the exists in this situation.)
from <expression> iterating over some POJOs (not facts) in a collection creates what I call "temporary facts", which, as facts, are limited to the context of the condition where the from clause is written. Thus, the Engine is not aware of any modification of a ChainStep object. ChainStep objects must be facts if you expect rules to react to their modification.
Basically, representing graphs by nodes as facts and with references to neighbours - up or down, or up and down, perhaps even including siblings, if it is a tree - is the way to go. But I'm not going to say more - see the initial paragraph.
I have many rule constraints that can be logically grouped together by "or". For example: 3 rules "r1", "r2" and "r3". I can construct a single LHS as:
(r1 || r2 || r3)
Or I can make each of them a separate rule. I have no critical functional requirement for doing it either way since I can detect their grouping independently outside of Drools.
I wonder if one way is more advantageous than the other from runtime execution perspective (performance, memory, etc.).
A disjunction at pattern level is handled very much like two different rules, so there's not much gained or lost either way.
But from a maintenance and development point of view, two separate rules require two copies of the right hand side, so using a disjunction in a single rule appears to be preferable.
Establishing binding variables used to be a little tricky but I think that recent versions (6.x) of Drools handle that satisfactorily.
Note that disjunctions at constraint level should definitely not be split into separate rules.
I have a scenario wherein I need to add rules to a rule engine dynamically.
What if I add same rule twice/multiple times?
I am not able to get exact behavior of Drools by doing POC(I am a newbie to Drools).
Also, if a rule once inserted remain in knowledgeBase until I explicitly remove it?
You cannot add the save rule twice (which is sufficient to rule out "multiple times"). If it is the "same", it simply replaces the previous "same" rule. If only the titles differ, then (it isn't the same rule and) you have two rules with the same LHS and the same RHS. This may, or may not, produces the same reaction a second time: this depends on what the RHS does or does not.
You can and should clarify these things by reading the documentation and/or experimenting with a simple setup.
Today I've been presented with a fun challenge and I want your input on how you would deal with this situation.
So the problem is the following (I've converted it to demo data as the real problem wouldn't make much sense without knowing the company dictionary by heart).
We have a decision table that has a minimum of 16 conditions. Because it is an impossible feat to manage all of them (2^16 possibilities) we've decided to only list the exceptions. Like this:
As an example I've only added 10 conditions but in reality there are (for now) 16. The basic idea is that we have one baseline (the default) which is valid for everyone and all the exceptions to this default.
Example:
You have a foreigner who is also a pirate.
If you go through all the exceptions one by one, and condition by condition you remove the exceptions that have at least one condition that fails. In the end you'll end up with the following two exceptions that are valid for our case. The match is on the IsPirate and the IsForeigner condition. But as you can see there are 2 results here, well 3 actually if you count the default.
Our solution
Now what we came up with on how to solve this is that in the GUI where you are adding these exceptions, there should run an algorithm which checks for such cases and force you to define the exception more specifically. This is only still a theory and hasn't been tested out but we think it could work this way.
My Question
I'm looking for alternative solutions that make the rules manageable and prevent the problem I've shown in the example.
Your problem seem to be resolution of conflicting rules. When multiple rules match your input, (your foreigner and pirate) and they end up recommending different things (your cangetjob and cangetevicted), you need a strategy for resolution of this conflict.
What you mentioned is one way of resolution -- which is to remove the conflict in the first place. However, this may not always be possible, and not always desirable because when a user adds a new rule that conflicts with a set of old rules (which he/she did not write), the user may not know how to revise it to remove the conflict.
Another possible resolution method is prioritization. Mark a priority on each rule (based on things like the user's own authority etc.), sort the matching rules according to priority, and apply in ascending sequence of priority. This usually works and is much simpler to manage (e.g. everybody knows that the top boss's rules are final!)
Prioritization may also be used to mark a certain rule as "global override". In your example, you may want to make "IsPirate" as an override rule -- which means that it overrides settings for normal people. In other words, once you're a pirate, you're treated differently. This make it very easy to design a system in which you have a bunch of normal business rules governing 90% of the cases, then a set of "exceptions" that are treated differently, automatically overriding certain things. In this case, you should also consider making "?" available in the output columns as well.
One other possible resolution method is to include attributes in each of your conditions. For example, certain conditions must have no "zeros" in order to pass (? doesn't matter). Some conditions must have at least one "one" in order to pass. In other words, mark each condition as either "AND", "OR", or "XOR". Some popular file-system security uses this model. For example, CanGetJob may be AND (you want to be stringent on rights-to-work). CanBeEvicted may be OR -- you may want to evict even a foreigner if he is also a pirate.
An enhancement on the AND/OR method is to provide a threshold that the total result must exceed before passing that condition. For example, putting CanGetJob at a threshold of 2 then it must get at least two 1's in order to return 1. This is sometimes useful on conditions that are not clearly black-and-white.
You can mix resolution methods: e.g. first prioritize, then use AND/OR to resolve rules with similar priorities.
The possibilities are limitless and really depends on what your actual needs are.
To me this problem reminds business rules engine where there is no known algorithm to define outputs from inputs (e.g. using boolean logic) but the user (typically some sort of administrator) has to define all or some the logic itself.
This might sound a bit of an overkill but OTOH this provides virtually limit-less extension capabilities: you don't have to code any new business logic, just define a new rule set.
As I understand your problem, you are looking for a nice way to visualise the editing for these rules. But this all depends on your programming language and the tool you select for this. Java, for example, has JBoss Drools. Quoting their page:
Drools Guvnor provides a (logically
centralized) repository to store you
business knowledge, and a web-based
environment that allows business users
to view and (within certain
constraints) possibly update the
business logic directly.
You could possibly use this generic tool or write your own.
Everything depends on what your actual rules will look like. Rules like 'IF has an even number of these properties THEN' would be painful to represent in this format, whereas rules like 'IF pirate and not geek THEN' are easy.
You can 'avoid the ambiguity' by stating that you'll always be taking the first actual match, in other words your rules have a priority. You'd then want to flag rules which have no effect because they are 'shadowed' by rules higher up. They're not hard to find, so it's something your program should do.
Your interface could also indicate groups of rules where rules within the group can be in any order without changing the outcomes. This will add clarity to what the rules are really saying.
If some of your outputs are relatively independent of the others, you will also get a more compact and much clearer table by allowing question marks in the output. In that design the scan for first matching rule is done once for each output. Consider for example if 'HasChildren' is the only factor relevant to 'Can Be Evicted'. With question marks in the outputs (= no effect) you could be halving the number of exception rules.
My background for this is circuit logic design, not business logic. What you're designing is similar to, but not the same as, a PLA. As long as your actual rules are close to sum of products then it can work well. If your rules aren't, for example the 'even number of these properties' rule, then the grid like presentation will break down in a combinatorial explosion of cases. Your best hope if your rules are arbitrary is to get a clearer more compact presentation with either equations or with diagrams like a circuit diagram. To be avoided, if you can.
If you are looking for a Decision Engine with a GUI, than you can try this one: http://gandalf.nebo15.com/
We just released it, it's open source and production ready.
You probably need some kind of inference engine. Think about doing it in prolog.