[rules-users] Maps in Drools

Edson Tirelli tirelli at post.com
Fri Aug 21 09:16:14 EDT 2009


2009/8/20 André Thieme <address.good.until.2009.dec.14 at justmail.de>

> Would there not be an addition to the syntax needed, for the default
> rule language? For mvel it would not require a change I guess.


No, as I mentioned to you, the idea is for the DRL to remain the same, so
that the rules author does not have to worry about what the IT guys are
doing with the domain model. So, the rules author would write:

Customer( name == "bob" )

The IT guy would simply use a configuration to tell the engine: this object
type uses a map format, that one is a POJO, that other is an XML entity,
etc.
For instance, if he wants to do that in DRL (he could also use API, or conf
files), he could do:

declare Customer
    @format( map )
end

declare Order
    @format( pojo )
end

So, we have a clear distinction between the technical aspects and the
business aspects of the application.

Your clojure macro would generate always the same DRL code "Customer( name
== "bob" )", but you said yourself that clojure is 100% java compatible, so
imagine the enterprise had a domain model implemented as pojos already and
as part of the new application some new entities are modeled in clojure. The
macro would generate always the same code, but you would configure some
entities in the domain as POJOs and other entities as Maps.


Hmm, but the MVEL syntax can not magically eliminate the eval. Under the
> hood the map accesses will still be inside an eval. Marc confirmed that
> a few days ago.
> MVEL only hides this from the user. This is what I will also do.
> But under the hood it will become
>
>   $a:Map()
>   $b:Map()
>   eval( $a.get("type") == "Customer" )
>   eval( $b.get("type") == "DailyOrders" )


Here I think we have other misunderstanding. I will try to explain, but
ideally you need to learn a bit about the Rete algorithm to see the whole
picture. There are 2 types of eval(). Inline eval() and top level eval().
What you wrote above is a top level eval, meaning it will become a node in
the rete network. So your example above generates an "execution plan"
(making an analogy with SQL) that will get all Maps in the working memory,
join them in tuples size 2, and then test each tuple for the 2 evals. So,
you see why this will generate C(n,2) partial matches, while C(n,2) as we
know is n!/(n-2)!, what is really bad for growing "n".

Now, the same thing could be written using inline evals as:

$a:Map( eval( $a.get("type") == "Customer" ) )
$b:Map( eval( $b.get("type") == "DailyOrders" ) )

  In this case, the inline eval() will generate an alpha constraint in the
network, i.e., it will be applied BEFORE the joins. So, instead of doing all
combinaions possible between all maps as above, it will first find all
Customer maps and all DailyOrders maps and only after that will make a join
between them. So you get Customers * DailyOrders partial matches. The above
evals are semantically equivalent as:

$a:Map( this[ "type" ] == "Customer" )
$b:Map( this[ "type" ] == "DailyOrders" )


> But currently I am forced to produce this cross product, as there is no
direct support for Maps yet.

I hope that by the above you see that the problem of the cross products is
not a problem with Maps support, but rather a question of how to write
better rules. The same way you can write 2 completely different SQL queries
that return the same result but one is fast and the other is completely
heavy and slow, you can also write good rules and really bad rules.

   []s
   Edson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090821/17ab12a6/attachment.html 


More information about the rules-users mailing list