[rules-users] Maps in Drools

André Thieme address.good.until.2009.dec.14 at justmail.de
Wed Aug 19 20:25:04 EDT 2009


Edson Tirelli schrieb:
> 
>     I will skip the first half of your e-mail as I am not sure what were 
> the reasons for your nit-picking. If my explanation was not helpful for 
> the public it was intended to, you are welcome to explain yourself.

Oh, I did not intend it to sound like nit-picking. I only meant that
with a specialized syntax one can make rules operating on Maps looking
basically identical to the ones operating on POJOs.


>     Regarding the part that matters, i.e., adding the support to other 
> fact types, Drools is prepared to support them in the LHS. Let me 
> explain by example:
> 
> when
>     $c : Customer( name == "bob" )
> then
> 
>    For the reasoning algorithm, does not matter if Customer is a POJO, 
> an XML document, a Map with the "type" attribute set to "Customer" as 
> you mentioned, or whatever you can think. We use a set of interfaces 
> that allows us to completely abstract that and we even supported 2 
> different fact types as a proof of concept in the past.

That sounds good!
So, in principle having Maps support in the LHS is not a big challenge?
As I understand it, code inside an eval can not be cached and needs to
get executed every time and results in less performant code.


>    The only reason we did not support multiple fact types yet for Drools 
> is the RHS. Our reasoning is that does not make sense to abstract the 
> LHS if you don't do the same for the RHS. So, for instance, using java 
> dialect:
> 
> when
>     $c : Person( name == "bob" )
> then
>     $c.setAge( 30 ) ;
> end
> 
>     If we will support that rule, written as is, for POJOs, and we want 
> to support Maps as facts, then our java parser needs to properly handle 
> the consequence code as $c.put("age", 30). Same thing if Person was an 
> XML document and so on.

 From my perspective the RHS is not important at all for my lib and for
Clojure users who like to work with Drools.
For me mostly one thing is interesting: getting Map lookups out of eval,
so they can profit from exactly the same caching and optimizations that
exist for POJOs.

The RHS will be fully written in Clojure, and all challenges that occur
in it would have to be solved by myself.
If you Drools Devs could make it possible to give support for Maps in
the LHS, then most issues for Clojure users could be solved.


> 
>     If you want to contribute to the project solving this problem, you 
> are most welcome.

Unfortunately I have not enough Java knowledege and not time.
But I would like to contribute indirectly, by writing a lib for Clojure
users which will make Drools easily accessible to them. It would also
provide other users of Drools with an alternative syntax, which gets
compiled into the default rule language. (Not into mvel, as that seems
to be interpreted and runs a bit slower.)


>     Regarding your rule rewrite, the way you propose is not feasible. 
> Using multiple patterns of the same type without proper alpha 
> constraints will lead to combinatorial explosion.

Could you please explain this in a bit more detail?
If Maps as 1st class rule objects, shouldn't my example then be exactly
the same as the one that you gave?

Your example was:

when
   Customer( $custId : id )
   DailyOrders( count[$custId] == 1 )
then ...


My example was:

rule "Rule name"
   when
     m1:clojure.lang.APersistentMap()
     m2:clojure.lang.APersistentMap()
     eval( m1.get("type") == "Customer" )
     eval( m2.get("type") == "DailyOrders" &&
          (m2.get("count")).get(m1.get("id")) == 1 )
   then
     ((clojure.lang.IFn)globalVarWithClojureCode.get(17)).call())
end


And with direct Map support it could become something like:

rule "Rule name"
   MapDefaultKey "type"
   Salience      2
   when
     "Customer"( $custId : "id" )
     "DailyOrders"( get("count", $custId) == 1 )
   then
     ((clojure.lang.IFn)globalVarWithClojureCode.get(17)).call())
end

Instead of the one could have syntactical sugar which may look
unfamiliar: "count"[$custId]

If the key is not a string but a float one would even have
88.5[$custId] instead get(88, $custId).
This is just a matter of taste, and users could have their DSLs anyway.


André
-- 
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org/



More information about the rules-users mailing list