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