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.

    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.

   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.

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

    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.

    []s
    Edson


2009/8/19 André Thieme <address.good.until.2009.dec...@justmail.de>

> Edson Tirelli schrieb:
> >
> > "On the general issue, is it received wisdom that it's better not to
> insert
> > map objects direct, at least for now until map support is fully there -
> or
> > is it 6 of one / half a dozen?"
> >
> >    Maps are data structures, not Domain entities.
>
> When we speak about equivalence in the mathematical sense then this
> statement is not true, as you say yourself:
>
> > Using maps as domain entities is possible,
>
> Exactly.
> Instead of a class Point with the fields x and y we could have a Map
> with the three slots "x", "y" and "type", where the makePoint method
> would always return a Map whose "type" key always is set to "Point".
>
> In Clojure this is an idiom. (Clojure is a language which compiles to
> Java Byte code and is fully compatible to the rest of Java.)
>
>
>  > but usually makes your rules unreadable.
>
> You are so deeply trained to think in Java that you forget the
> possibility of other syntaxes, in which it is perfectly readable.
>
>  > That is  why it is bad to use any data structures or simple numbers,
>  > strings, dates as isolated facts...
>  > they don't have a well known business  semantic in a given
>  > business model (not to mention how they get mixed
> > with each other and cause cross products, etc). A rule like the
> > following has no explicit meaning:
> >
> >        when
> >                $str: String()
> >                $m: Map( this[$str] == 1 )
> >        then
> >
> >     But when you write something like:
> >
> >         when
> >                Customer( $custId : id )
> >                DailyOrders( count[$custId] == 1 )
> >         then
> >
> >     Things are clear just by looking at them, even if $custId is a
> > String and count is a Map as in the original example.
>
> But now think about how this could be in Clojure.
> We would have a macro map-rule which tells Drools that we are using
> exclusively maps, and it may look like:
> (map-rule "Rule name", "type"
>   (when
>     "Customer" ( $cust-id "id" )
>     "DailyOrders" (= 1 (get "count" $cust-id)))
>   (then
>     (println "match")))
>
> The first argument is here "type" and tells the macro, that all maps do
> have a key "type". It now dispatches to those. In the when part we first
> look at all Maps of type "Customer".
> They may look like:
> {"id" 4,  "name" "Carlos",  "type" "Customer"}
> {"id" 1,  "name" "Tina",  "type" "Customer"}
>
> Then we look at all Maps of type "DailyOrders". Those Maps may look like:
> {"id" 27,
>  "day" <java.util.Date Object>,
>  "count" {4 "abc",  18 "xyz"},
>  "type" "DailyOrders"}
>
> get takes the key under which a DailyOrders instance has another Map as
> value, and accesses is with the key which is the second value here,
> the $cust-id.
> The when part looks exactly the same, only that I did not use the
> syntactic sugar for accessing maps.
>
> As soon I have enough time in the coming days I will write a Clojure lib
> which will make Drools easily usable from within Clojure.
> The good thing about that is that rules are not longer strings - they
> now become code. And because in Clojure  Code = Data  we will have the
> full power of Lisp available, and can write programs that write programs,
> such as rules. This easily opens rules to be automatically created via
> Genetic Programming, or, if the search space is not too huge, then all
> combinations of rules can be generated and tried out, to see which of
> those 18000 can solve my domain specific problem best.
>
>
> Currently the rule I showed above would become a Drools rule like:
> 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
>
> This would happen under the hood, and it would not be exposed to the
> users of my lib. I did not test this specific example code, and maybe
> I got something wrong, but that is the basic idea. Drools can work with
> this and does not have the readability problems of humans.
> In Clojure we can easily eliminate all readability isseus. I will offer
> some few macros for defining rules, and users can simply add others if
> they want. They won't have to care about what the underlying real Drools
> rules syntax looks like. They only expand their macros into my existing
> ones and have automatically optimized code, adopted to their readability
> needs in their specific domain.
>
>
> Now if the Drools Devs find a way how it would be possible to add the
> same optimization support for Maps as they currently already exist for
> POJOs, then rules acting on Maps could be very fast.
> I understand that the call to the method get() itself will be slower,
> because a hash value needs to be computed before the lookup can be made,
> but I think that lookup will not be the bottleneck.
> It would be fantastic if the Drools Devs could make it the bottleneck.
> In that case, that Maps would not need to be placed in eval anymore and
> become 1st class objects, exactly as POJOs, then get() would be the
> slowest part (which is now eval and full execution without caching).
>
> And Clojure Maps are also immutable. Drools can be certain that nothing
> in the Maps changes (btw, Clojure vectors and lists are also immutable),
> and that may lead to even more optimizations.
> Perhaps there could be another method for inserting objects, such as
> session.insertImmutable() or session.insertPersistent().
> Inserting an object X in such a way would tell Drools that X can't be
> mutated and thus other optimizations can be applied.
>
>
> André
> --
> Lisp is not dead. It’s just the URL that has changed:
> http://clojure.org/
> _______________________________________________
> rules-users mailing list
> rules-users@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>



-- 
 Edson Tirelli
 JBoss Drools Core Development
 JBoss by Red Hat @ www.jboss.com
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users

Reply via email to