I have often said that for rule engines, it is a "dirty little secret" that fact modelling/ontologies/service interface definitions are the most difficult part - hardest to get right (and often needed somewhat upfront). Of course you can use a TDD approach to "evolve" this to some extent, but of course that is a development activity.
As tools improve over time, this will get easier, but modelling the business domain both accurately, and to make it "friendly" for rules will always require some level of skill (Knowedge Engineer is a term that used to be used).
ILog JRules uses the "BOM" approach, other engines like Corticon take a model driven approach, all good approaches, but none of them easy. Some are easy to integrate into your project (like with Drools, facts are Pojos, same as with Ilog), others require you to implement facts as specific interfaces/classes, or call the engine as a "decision service" - in all cases there are considerable overhead to getting it integrated into your app.
Also, if you see that the object model requires complex joins to support most of the rules you need, then it will be hard to maintain for a less technical person (of course there are a class of problems that can be solved with simple rules over flat fact models (but not ALL of the problem).
If you are flexible with your fact model, you will get better results from the rules point of view, but the price you pay is to map between the fact model and you real domain object model for your application (hence why some people want to use the domain object model directly).
Hopefully I will write a blog with some more info on fact modelling, and the different approaches people take.
There is no silver bullet, and if there was, it would only be good for vampires ;)
On 11/10/06, gabriel quennesson <[EMAIL PROTECTED]> wrote:
I was just stating that including a rule engine into a business
application is not as straightforward as one would like to believe it,
and does not add such great modularity. After some time of using them
(first mandarax, then drools) my level of expectation greatly
diminished, and some aspect I had not foresee arised : Unability to
actually have a third party maintain the rulebase, the all-importance of
having the correct object model from the begining. Now it probably would
have been expected had I more expecience on the subject. I'm probably
missing the "Rule engine integration and Rulebase design HOWTO" I now
have in my head after some time of struggling.
I, for myself, used RE more or less successfully for 3 application (2 of
which are now on end-users desktop). As I stated earlier, even if it
were only for many-to-many matching, RE as drools are worth using.
As for why it ended in the discussion: I don't know really. It kind of
poped into my mind as you were correcting the above design flaws. If it
invalidate my point, please excuse, I just thought it was worth
discussing - is it the place and time I don't know either.
Edson Tirelli a écrit :
> Gabriel,
>
> Well observed.
> Just adding to the discussion, real world applications bring many
> problems for us IT professionals. I agree with your points, but note
> that they are not exclusive for rules engines. Any technology or tool
> set introduced in a high complex development environment will present
> the same kind of problems (modelling complexity, change management
> over time and technical/technological specialist requirements).
> So, best we can do (IMHO) is try to reduce or simplify these
> problems through experience, methodologies, etc. One of the more
> popular ways of doing it is through use of best practices. So, my
> point in my previous (long) e-mail was simply a best practice:
>
> * when working with rules, try to avoid hard code your constraint values.
>
> So, comparing to original post, don't do name == "XXX" because you
> know XXX is a player that plays in position #1. Prefer to have a
> position attribute over which you can constraint.
> In a similar way, if you have age constraints for tournments, try to
> avoid doing rules with age < X and age > Y. Create a class to
> represent the constraint (Tournment) and write rules constraining by
> this class instances.
> Doing it will make rules easier do develop and maintain as it will
> reduce the amount of rules, avoid nested operators, etc.
>
> So, my understanding is that the above is a different subject than
> the one you mentioned in your last sentence.
> Why do feel that the advertised aspects are "greatly overrated"?
>
> PS: I developed a project some months ago where the engine was also
> used as a discrimination network, nothing else. I guess it is one
> valid use case, isn't it?
>
> []s
> Edson
>
> gabriel quennesson wrote:
>
>> Obviously, a correct and well designed object model is mandatory to
>> ensure rule engine success.
>>
>> However, I would like to point a few problems I faced as a rule
>> engine enthousiast in the industry :
>>
>> - Maping real world datas to the correct object model is an issue,
>> - starting with the correct object model requires a tremendous design
>> effort prior to developpement, and such a design will leads to
>> non-evolutive application which defeat the purpose of rule engines
>> (no to mention the "old school" aspect of such a design cycle, new
>> method being about TDD or hardcore coding),
>> - Rule language (with the notable exception of some products,
>> including decision table, with their limitations) require a "Rule
>> specialist" function to exists -most probably one of the developper
>> himself.
>>
>> So I'm ok to point the design flaw we users commit, but one has to
>> see the reality of business developpement.
>>
>> So far I use drools as a powerfull many-to-many matching algorythm.
>> All advertised aspects of rule engines (separation of concerns with
>> human readable rules, code-free or even runtime evolution of
>> behaviour etc) I find to be greatly overrated.
>> I'd be happy to share opinions on the subject.
>>
>> Edson Tirelli a écrit :
>>
>>>
>>> Hello all,
>>>
>>> I would like to suggest we return to the beggining here to explore
>>> interesting ways for a football manager and coaches to use JBRules. :)
>>> First of all, lets define a possible object business model. Lets
>>> start with a single class (pseudo code):
>>>
>>> class Player {
>>> String name;
>>> String position;
>>> int skill; // how good the player is: grade from 0 to 10.
>>> int age;
>>> double salary;
>>>
>>> // getters and setters
>>> }
>>>
>>> Ok, so, we have a set of players asserted into working memory.
>>> Lets say now, the manager asks the coach to define who will be the
>>> main team for the next season, and the coach wants to use his best
>>> player for each position. A rule like this one could be used:
>>>
>>> global java.util.List mainTeam;
>>>
>>> rule "Main Team"
>>> $player: Player( $name: name, $skill: skill, $position: position)
>>> not Player( position == $position, skill > $skill )
>>> then
>>> System.out.println(" The best player for position
>>> "+$player.getPosition()+" is "+$player.getName() );
>>> mainTeam.add($player);
>>> end
>>>
>>> So, using this single rule, the coach will cast his best player
>>> for each position.
>>> Now, lets say, all tournments have age constraints. So, the coach
>>> wants to know his best team for each tournment, matching age
>>> constraints. So, lets improve our business model to allow Tournments
>>> to be defined:
>>>
>>> class Tournment {
>>> String name;
>>> int minimumAge;
>>> int maximumAge;
>>> List team;
>>> // getters and setters
>>> }
>>>
>>> So, now, we can change our rule to take tournments into account:
>>>
>>> rule "Team for each tournment"
>>> $tournment : Tournment( $minAge: minimumAge, $maxAge: maximumAge )
>>> $player: Player( $name: name, $skill: skill, $position: position,
>>> age >= $minAge, age <= $maxAge )
>>> not Player( position == $position, skill > $skill, age >= $minAge,
>>> age <= $maxAge )
>>> then
>>> $tournment.addPlayerToTeam( $player );
>>> end
>>>
>>> As you can see by above examples, it is always good to define
>>> rules in terms of our business model and usually not use "hardcoded"
>>> constraints. This will make for clear and more maintainable rules,
>>> as well as avoid an "infinite" sequence of nested "or" and "and"
>>> operators.
>>> What if a team must be under a certain total salary cost? What if
>>> players can't join more than X silmultaneous tournments? It is
>>> always simple and straightforward to define this kind of rule, as
>>> long as you have a good business model with supporting data.
>>> Having said that, JBRules does support nested "or" and "and"
>>> operators (though it does not support "not" with nested operators
>>> inside it), but it is important to note that the top level "or"
>>> operator in rules engines (this is not JBRules specific) will
>>> effectivelly create multiple rules in the backend. So, if you say:
>>>
>>> rule "A"
>>> ClassX(<constraints>) || ClassY( <constraints> )
>>> then
>>> ..
>>> end
>>>
>>> It is only syntax sugar, as it will compile to:
>>>
>>> rule "A1"
>>> ClassX(<constraints>)
>>> then
>>> ..
>>> end
>>>
>>> rule "A2"
>>> ClassY( <constraints> )
>>> then
>>> ..
>>> end
>>>
>>> If you have a complex sequence of nested "and" and "or" operators,
>>> it will use Morgan's theorem to transform it in a disjunction of
>>> conjunctions, i.e., a top level "or" with "and"s beneath it. After
>>> that, it will break the "or" making each logical branch a single
>>> subrule. Again, this is not JBRules specific, but general rules
>>> engine's behavior.
>>>
>>> Sorry for the long e-mail, but I hope this brings some light to
>>> the subject under discussion, i.e., I hope our football managers and
>>> coaches continue to use JBRules and winning tournments! ;)
>>>
>>> Let me know if you guys have any question or issue you would like
>>> to discuss further, and thanks for bringing some fun and good humor
>>> to the list!
>>>
>>> []s
>>> Edson
>>>
>>> John Cocktolstoy wrote:
>>>
>>>> First - thanks for answers.
>>>>
>>>> So, basically I could use evaluation such as:
>>>>
>>>> Player1 ( hisage : age -> ( compare(hisage, 19, 21) ) )
>>>>
>>>> or even, without the inline function:
>>>>
>>>> Player1 ( hisage : age -> ( (age == 19) || (age == 21)) ) )
>>>>
>>>> This is equivalent to what Matias did although he put it into dsl.
>>>>
>>>> As to what is stated in documentation, it indeed suggest that man
>>>> can create rule like in algebra with grouping and nesting "and"s
>>>> and "or"s. From my experience it all work as long as you don't nest.
>>>>
>>>> regards
>>>> John
>>>>
>>>>
>>>> On 11/8/06, *gabriel quennesson*
>>>> < [EMAIL PROTECTED]
>>>> <mailto:[EMAIL PROTECTED]>> wrote:
>>>>
>>>> That's why I said It probably wasn't the answer you expected.
>>>> You could use an inline function that would compare the value and
>>>> return
>>>> true if it matches one argument or the other :
>>>>
>>>> when
>>>>
>>>> Player1 ( hisage : age -> ( compare(hisage, 19, 21) ) )
>>>>
>>>> then
>>>>
>>>> doStuff();
>>>>
>>>> end
>>>>
>>>> function boolean compare(int age, int firstValue, int
>>>> secondValue) {
>>>>
>>>> if (age == firstValue)
>>>>
>>>> return true;
>>>>
>>>> if (age == secondValue)
>>>>
>>>> return true;
>>>>
>>>> return false;
>>>>
>>>> }
>>>>
>>>>
>>>> But I must admit it is not very clean either.
>>>>
>>>> Now, in drools doc section * 3.23 *it is stated you can group
>>>> using
>>>> parenthesis and keywords, pretty much like you would in algebra. I
>>>> abandoned the idea though, and did the same by writing several
>>>> rules.
>>>>
>>>> John Cocktolstoy a écrit :
>>>> > Thanks for the answer!
>>>> > Yep, in case of String types I could use 'matches' . But what if
>>>> each
>>>> > player have also field:
>>>> > int age
>>>> > and instead of names I would like to compare age of players?
>>>> How to
>>>> > cope with that?
>>>> >
>>>> > As to the second idea - I think I can't just write the rule the
>>>> exact
>>>> > way I did with "and" and "or" keywords. I believe it is
>>>> impossible to
>>>> > nest "and"s and "or"s. Am I right? I also wasn't able to
>>>> successfully
>>>> > write such a rule.
>>>> >
>>>> > regards
>>>> > John
>>>> >
>>>> > On 11/8/06, *gabriel quennesson*
>>>> < [EMAIL PROTECTED]
>>>> <mailto:[EMAIL PROTECTED]>
>>>> > <mailto: [EMAIL PROTECTED]
>>>> <mailto:[EMAIL PROTECTED]>>> wrote:
>>>> >
>>>> > I'm not sure this is the answer you expect but you could
>>>> do the
>>>> > following :
>>>> >
>>>> > when
>>>> >
>>>> > Player1 (name matches "Roy|Bob")
>>>> >
>>>> > Player2(name matches "Tom|Eric")
>>>> >
>>>> > ...
>>>> >
>>>> > Player11(name matches "Paulo|Ryan")
>>>> >
>>>> > then
>>>> >
>>>> > doStuff();
>>>> >
>>>> > end
>>>> >
>>>> >
>>>> >
>>>> > In some trickier cases, you could use functions to
>>>> perform other
>>>> > forms of matching.
>>>> >
>>>> > Or you could just write the rule the exact way you did with
>>>> "and"
>>>> > and "or" keywords, which is documented in Drools (I wasn't
>>>> able to
>>>> > successfully write such a rule, though).
>>>> >
>>>> > Regards,
>>>> >
>>>> > Gabriel
>>>> >
>>>> > John Cocktolstoy a écrit :
>>>> >> Hi,
>>>> >>
>>>> >> I am new to Drools, I just read documentations and went
>>>> through
>>>> >> some examples.
>>>> >> I am wondering about the following example (I spiced it up
>>>> with a
>>>> >> story so it should not be boring :-) ):
>>>> >>
>>>> >> Suppose I am a football manager and trying to use Drools to
>>>> >> automate some processes.
>>>> >> I have 11 classes (these are going to be facts):
>>>> >> Player1, Player2, Player3, ..., Player11
>>>> >> One for each player of my team, each of class has one
>>>> field:
>>>> >> String name
>>>> >> In run-time I will assert into working memory only one
>>>> instance
>>>> >> of each class as I would like to evaluate some rules
>>>> over my
>>>> >> current team.
>>>> >> Now I would like to create simple rule - I express it in
>>>> >> pseudo-language:
>>>> >>
>>>> >> when
>>>> >> ((Player1.name <http://Player1.name>
>>>> < http://player1.name/> == "Roy") or (
>>>> >> Player1.name <http://Player1.name > <http://player1.name/>
>>>> == "Bob"))
>>>> >> and
>>>> >> (( Player2.name <http://Player2.name>
>>>> <http://player2.name/> == "Tom") or (
>>>> >> Player2.name <http://Player2.name> <http://player2.name/>
>>>> == "Eric"))
>>>> >> and
>>>> >> ...
>>>> >> and
>>>> >> ((Player11.name < http://Player11.name>
>>>> <http://player11.name/> == "Paulo") or
>>>> >> (Player11.name <http://Player11.name>
>>>> <http://player11.name/> == "Ryan"))
>>>> >> then
>>>> >> do something
>>>> >>
>>>> >> Could anyone show me how to express this rule using Drools
>>>> >> without going into huge number of rules? As I understand
>>>> from
>>>> >> documentation each 'or' is creating two sub-rules. Isn't
>>>> that
>>>> >> limitation that makes Drools useless for football managers?
>>>> >>
>>>> >> regards
>>>> >> John
>>>> >
>>>> >
>>>>
>>>> --
>>>>
>>>> ___________________
>>>> *Gabriel Quennesson *| CTC/I | *SEAM*
>>>> Int :* *7 906 6910 | Ext: 04 73 64 69 10
>>>> [EMAIL PROTECTED]
>>>> <mailto:[EMAIL PROTECTED]>
>>>> <mailto: [EMAIL PROTECTED]
>>>> <mailto:[EMAIL PROTECTED]>>
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe from this list please visit:
>>>>
>>>> http://xircles.codehaus.org/manage_email
>>>> <http://xircles.codehaus.org/manage_email>
>>>>
>>>>
>>>
>>>
>>
>
>
--
___________________
*Gabriel Quennesson *| CTC/I | *SEAM*
Int :* *7 906 6910 | Ext: 04 73 64 69 10
[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
