[rules-users] Collecting / sorting by the number of matches
Hi, ta very much everyone for the help so far. Another question - how to sort by number of matches please? Say I have objects A, B, C and D and rules 1 to 5. Each object can match each rule independently e.g. A can match rule 1 and 2, B might match all rules 1 to 5, C might match none, D rules 3 and 4 etc. I need to rank them and then print out info about them in order of number of matches, with an indication of which rules matched, i.e. print info on B before A but nothing at all on C, etc. In Java I'd probably do it by having, as a global variable, a map where the key is the name or ID field of the object and the value is an arraylist which gets added to in the consequence (with a string about what kind of match it was i.e. which rule was matched) whenever there's a match on a rule for that object. Then sort it by descending length of the arraylists. There has to be a better and more elegant way of doing it in Drools, probably involving collecting info on the matches and then sorting them, but I can't think what or how. Does anyone have any thoughts or suggestions please? Many thanks in advance. -- View this message in context: http://www.nabble.com/Collecting---sorting-by-the-number-of-matches-tp25039921p25039921.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] How to create nested rules in Drool Guvnor
Michael Rhoden wrote: You can do this using the extends keyword in your rule. You can't use extends in the rule header. -- View this message in context: http://www.nabble.com/How-to-create-nested-rules-in-Drool-Guvnor-tp24943230p25043217.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Collecting / sorting by the number of matches
Take a look at the *AgendaEventListener*. It allows you to get callbacks for when a rule has fired. This would allow you to keep track of which rules fire along with the objects that caused it to fire. On Wed, Aug 19, 2009 at 4:27 AM, KDR dr.sopr...@neverbox.com wrote: Hi, ta very much everyone for the help so far. Another question - how to sort by number of matches please? Say I have objects A, B, C and D and rules 1 to 5. Each object can match each rule independently e.g. A can match rule 1 and 2, B might match all rules 1 to 5, C might match none, D rules 3 and 4 etc. I need to rank them and then print out info about them in order of number of matches, with an indication of which rules matched, i.e. print info on B before A but nothing at all on C, etc. In Java I'd probably do it by having, as a global variable, a map where the key is the name or ID field of the object and the value is an arraylist which gets added to in the consequence (with a string about what kind of match it was i.e. which rule was matched) whenever there's a match on a rule for that object. Then sort it by descending length of the arraylists. There has to be a better and more elegant way of doing it in Drools, probably involving collecting info on the matches and then sorting them, but I can't think what or how. Does anyone have any thoughts or suggestions please? Many thanks in advance. -- View this message in context: http://www.nabble.com/Collecting---sorting-by-the-number-of-matches-tp25039921p25039921.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] not able to debug drools flow
Hello I have the same problem when debuging rules using eclipse 3.5, drools 5.0 and jdk 1.6. I downgraded to eclipse 3.4 and worked for me. Is there a solution to let me debug using eclipse 3.5? Thanks Max Hi, I`m experiencing the same problems as Vishal. I am using Eclipse 3.5 and newest Drools. I am only able to debug project as Java application, but when I want to debug it as Drools application all I get is this problem. I also tried disabling firewall and changing its settings but as it seems it does not help. So if anyone has figured out a solution to this problem, I would really appreciate an answer. Thanks, Jakob probably related to your personal firewall: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6303969 http://www.techienuggets.com/Comments?tx=3786 I don't think this is a Drools specific issue. Mark Vishal Anand wrote: *** Hi,* *** * *** I am using Drools 5.0 and have create a simple application using * * drools flow, it runs perfectly but when trying to debug it as n drools * * application I get the following error:* *** * *** FATAL ERROR in native method: JDWP No transports initialized, * * jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197)* *** ERROR: transport error 202: connect failed: Connection refused* *** ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)* *** JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports * * initialized [../../../src/share/back/debugInit.c:690]* *** * *** * *** While stack trace shows the following:* *** * *** * *** java.lang.IncompatibleClassChangeError: Expected static method * *org.drools.eclipse.launching.DroolsVMDebugger.renderCommandLine([Ljava/lang/String;)Ljava/lang/String; * *** at org.drools.eclipse.launching.DroolsVMDebugger.run(Unknown Source)* *** at * *org.eclipse.jdt.launching.JavaLaunchDelegate.launch(JavaLaunchDelegate.java:101) * *** at * *org.drools.eclipse.launching.DroolsLaunchConfigurationDelegate.launch(Unknown * * Source)* *** at * *org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:853) * *** at * *org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:703) * *** at * *org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:866) * *** at * *org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1069) * *** at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)* *** * *** * *** I am using eclipse 3.4* *** * *** What could be the issue ?* *** * *** Thanks* *** Vishal* ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Collect from
Remember that collect is a simplified form of accumulate. So when you can't achieve what you want with collect, first thing you should look for is accumulate. $list : List() from accumulate( $foo : Foo( ) and not Bar( id == $foo.id ), collectList( $foo ) ) Please note that I changed your example making the constraint in Bar use == instead of != because I think that is what you want. But if it is not, just use whatever expression you want. Also be aware that collect/accumulate are heavy CEs. Nesting multiple patterns inside accumulate is even heavier, so use it wisely. Hope it helps, Edson 2009/8/18 techy techluver...@gmail.com Please someone help me on this. techy wrote: I would like to collect All Foo() for which there is no Bar() as given below.Please help me on this. Thanks. //psedo rule rule 'test' list : from collect( Foo(fooId: id) and not Bar(id !=fooId)) then //do conseq end -- View this message in context: http://www.nabble.com/Collect-from-tp25014904p25029332.html Sent from the drools - user mailing list archive at Nabble.com. ___ 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
Re: [rules-users] Is emptieness supported in Drools 5 (LHS)
Sometimes this is indeed not clear, so I will try to explain here. Drools uses MVEL to resolve some expressions and semantic code. Although we would like to make it 100% compatible and enable it to use mvel everywhere, that is easier said than done (but we do have someone working on that). Anytime you want to force Drools to fallback into MVEL (or java, as the other supported dialect) you need to place your code inside an eval(). For some well known situations, Drools does this automatically, but that is not the case with empty. For now, in your case, you could either do: MyGrabBag( someMap != null, someMap.empty == true ) Or if you are using mvel as your rule dialect: MyGrabBag( eval( someMap == empty ) ) []s Edson 2009/8/18 Pegram, Macon zmpeg...@choosehmc.com According to MVEL they’ve added a convenience for checking the “emptiness” of a value (see: http://mvel.codehaus.org/Value+Tests ) In MVEL you’d simply write: myMap == empty This seemed like a MUCH cleaner way to write some of the LHS of the rules, so I thought I’d try it out. Given the following rule: *rule* Check Empties - Original *when * $grabBag : MyGrabBag(someMap != null) *eval* ($grabBag.getSomeMap().size() == 0) *then* *end* * * This could be rewritten: * * *rule* Check Empties - Simple *when * MyGrabBag(someMap == *empty*) *then* *end* The IDE (Eclipse 3.4.2 w/ Drools plugin) seems to recognize “empty” is a keyword (it makes it bold), but the drools compiler in the IDE reports: BuildError: Unable to create restriction '[VariableRestriction: == empty ]' for field 'someMap' in the rule 'Check Empties - Simple' BuildError: Unable to return Declaration for identifier 'empty' Am I assuming incorrectly that the LHS is fully MVEL compliant? ___ 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
Re: [rules-users] Is emptieness supported in Drools 5 (LHS)
Edson, Thanks for clarifying this. I appreciate it. Macon 2009/8/19 Edson Tirelli tire...@post.com Sometimes this is indeed not clear, so I will try to explain here. Drools uses MVEL to resolve some expressions and semantic code. Although we would like to make it 100% compatible and enable it to use mvel everywhere, that is easier said than done (but we do have someone working on that). Anytime you want to force Drools to fallback into MVEL (or java, as the other supported dialect) you need to place your code inside an eval(). For some well known situations, Drools does this automatically, but that is not the case with empty. For now, in your case, you could either do: MyGrabBag( someMap != null, someMap.empty == true ) Or if you are using mvel as your rule dialect: MyGrabBag( eval( someMap == empty ) ) []s Edson 2009/8/18 Pegram, Macon zmpeg...@choosehmc.com According to MVEL they’ve added a convenience for checking the “emptiness” of a value (see: http://mvel.codehaus.org/Value+Tests ) In MVEL you’d simply write: myMap == empty This seemed like a MUCH cleaner way to write some of the LHS of the rules, so I thought I’d try it out. Given the following rule: *rule* Check Empties - Original *when * $grabBag : MyGrabBag(someMap != null) *eval* ($grabBag.getSomeMap().size() == 0) *then* *end* * * This could be rewritten: * * *rule* Check Empties - Simple *when * MyGrabBag(someMap == *empty*) *then* *end* The IDE (Eclipse 3.4.2 w/ Drools plugin) seems to recognize “empty” is a keyword (it makes it bold), but the drools compiler in the IDE reports: BuildError: Unable to create restriction '[VariableRestriction: == empty ]' for field 'someMap' in the rule 'Check Empties - Simple' BuildError: Unable to return Declaration for identifier 'empty' Am I assuming incorrectly that the LHS is fully MVEL compliant? ___ 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 ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Unique events / facts in working memory
Greg is right if you want to keep it just using expert features. Now if you model your Singleton as an event, you could use the timestamp instead of create a specific attribute for that: oldSingleton : Singleton( $id : id ) newSingleton : Singleton( id == $id, this after oldSingleton ) Or, if you have just a few rules that use your Singleton and you activate the STREAM mode, you could simply use a sliding window: rule my rule that uses the singleton when $singleton : Singleton( ... ) over window:length(1) // more patterns... then // do something end []s Edson 2009/8/18 Greg Barton greg_bar...@yahoo.com You need some comparable property in the singleton object that's monotonically increasing. Then you can have a rule like the following that must be of higher salience than the rules you want to protect from duplicate singletons. i.e.: rule EnforceOneSingleton when oldSingleton : Singleton( $id : id, $version : version ) newSingleton : Singleton( id == $id, version $version) then System.out.println( Retracting old Singleton + oldSingleton.getId() + version + oldSingleton.getVersion()); retract( oldSingleton ); end --- On Mon, 8/17/09, Justin King justin.matthew.k...@gmail.com wrote: From: Justin King justin.matthew.k...@gmail.com Subject: [rules-users] Unique events / facts in working memory To: Rules Users List rules-users@lists.jboss.org Date: Monday, August 17, 2009, 6:20 PM I'm building an application that will over time record changes in a certain component (not at any set interval, could occur any time). The component can possibly be uniquely identified via some kind of id. Is there a way that when I insert an event / fact recording a change of state in this component I can remove the previous one, so as there is only ever one fact / event recording the current state of the component. If the previous one existed it may cause rules to fire which should not. Cheers, Justin -Inline Attachment Follows- ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ 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
Re: [rules-users] Collecting / sorting by the number of matches
Thank you Dave. I had a look, but it seems I'd still have to track it and process the results in Java rather than using rules, so I guess I'll stick with my original Java solution. Unless there's some way to track it in Drools? Cheers dave sinclair wrote: Take a look at the *AgendaEventListener*. It allows you to get callbacks for when a rule has fired. This would allow you to keep track of which rules fire along with the objects that caused it to fire. -- View this message in context: http://www.nabble.com/Collecting---sorting-by-the-number-of-matches-tp25039921p25045478.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Collecting / sorting by the number of matches
Just remember that doing it this way alleviates the author of the rules from having to add that book keeping when creating new rules. This may not be a *rule based* solution, but it is a *Drools* solution :) On Wed, Aug 19, 2009 at 10:42 AM, KDR dr.sopr...@neverbox.com wrote: Thank you Dave. I had a look, but it seems I'd still have to track it and process the results in Java rather than using rules, so I guess I'll stick with my original Java solution. Unless there's some way to track it in Drools? Cheers dave sinclair wrote: Take a look at the *AgendaEventListener*. It allows you to get callbacks for when a rule has fired. This would allow you to keep track of which rules fire along with the objects that caused it to fire. -- View this message in context: http://www.nabble.com/Collecting---sorting-by-the-number-of-matches-tp25039921p25045478.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Maps in Drools
Thanks again Edson. I'd just used a String object to try a simple test but of course your example makes a lot more sense. And thanks also for clarifying that there's full syntax support in the latest mvel jar version. I know this is a Drools rather Java list but as I'm new to both, may I ask further how to install that new jar version you mentioned into my current Eclipse Drools project, or indeed how to get new Drools projects in Eclipse to use it please, instead of the old version? I've tried copying the jar into the Drools runtime folder but it doesn't work? Cheers Edson Tirelli-3 wrote: 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. Using maps as domain entities is possible, but usually makes your rules unreadable. 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. Regarding the bug, it was a regression that was fixed. All the syntax support we intended to have for them is in Drools. Not sure what you mean by support is fully there. Hope it helps. []s Edson -- View this message in context: http://www.nabble.com/Maps-in-Drools-tp25031348p25045607.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Extending the validation of rules functionality in Guvnor
Hello everyone, Currently, the validate functionality ensures that rules have proper syntax. it is possible to extend this functionality so that business use cases might also be validated? Is there an API/examples to do that. For eg, in our domain, an object X can be evaluated for 3 criteria ( a, b, c ) However, we would need to prevent rules written which combine criteria b and c Rules can have the combinations ( a,b,c, ab, ac ). Combinations ( bc and abc ) should not be allowed. Regards, Prem ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Maps in Drools
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
Re: [rules-users] not able to debug drools flow
Thank you for your suggestion Maximiliano, debugging really works in Eclipse version 3.4 for me. So the problem is probably in compatibility with 3.5 (but maybe just on few specific configurations). Bye On Wed, Aug 19, 2009 at 3:28 PM, Maximiliano Batelli maxibate...@gmail.comwrote: Hello I have the same problem when debuging rules using eclipse 3.5, drools 5.0 and jdk 1.6. I downgraded to eclipse 3.4 and worked for me. Is there a solution to let me debug using eclipse 3.5? Thanks Max Hi, I`m experiencing the same problems as Vishal. I am using Eclipse 3.5 and newest Drools. I am only able to debug project as Java application, but when I want to debug it as Drools application all I get is this problem. I also tried disabling firewall and changing its settings but as it seems it does not help. So if anyone has figured out a solution to this problem, I would really appreciate an answer. Thanks, Jakob probably related to your personal firewall: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6303969 http://www.techienuggets.com/Comments?tx=3786 I don't think this is a Drools specific issue. Mark Vishal Anand wrote: *** Hi,* *** * *** I am using Drools 5.0 and have create a simple application using * * drools flow, it runs perfectly but when trying to debug it as n drools * * application I get the following error:* *** * *** FATAL ERROR in native method: JDWP No transports initialized, * * jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197)* *** ERROR: transport error 202: connect failed: Connection refused* *** ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)* *** JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports * * initialized [../../../src/share/back/debugInit.c:690]* *** * *** * *** While stack trace shows the following:* *** * *** * *** java.lang.IncompatibleClassChangeError: Expected static method * *org.drools.eclipse.launching.DroolsVMDebugger.renderCommandLine([Ljava/lang/String;)Ljava/lang/String; * *** at org.drools.eclipse.launching.DroolsVMDebugger.run(Unknown Source)* *** at * *org.eclipse.jdt.launching.JavaLaunchDelegate.launch(JavaLaunchDelegate.java:101) * *** at * *org.drools.eclipse.launching.DroolsLaunchConfigurationDelegate.launch(Unknown * * Source)* *** at * *org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:853) * *** at * *org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:703) * *** at * *org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:866) * *** at * *org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1069) * *** at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)* *** * *** * *** I am using eclipse 3.4* *** * *** What could be the issue ?* *** * *** Thanks* *** Vishal* ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Maps in Drools
Edson Tirelli schrieb: when Customer( $custId : id ) DailyOrders( count[$custId] == 1 ) then Btw, this brings me to a new syntax question for the default Drools rule syntax. Is this possible: when m:Map() eval( m.get(type) == Point, $x : m.get(x) ) ... Circle( x == $x ) then ... or, an alternative which may be clearer: when m:Map() eval( m.get(type) == Point ) $x : m.get(x) ... then ... So, what I would like to have is: 1) looking at all Maps which have the value Point under the key type 2) of all those Maps: store in a var what value they have under key x 3) reuse the var, here $x instead of having an expensive lookup over and over again. Is that possible? Or would I have to write my example above as ... c:Circle() eval(c.getX() == m.get(x)) 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
Re: [rules-users] Maps in Drools
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
Re: [rules-users] Maps in Drools
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/ ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Maps in Drools
ooops... correct version: when Map( this[type] == Point, $x : this[x] ) Map( this[type] == Circle, this[x] == $x ) then end 2009/8/19 Edson Tirelli tire...@post.com when Map( this[type] == Point, $x : this[x] ) Map( this[type] == Circle, x == $x ) then end 2009/8/19 André Thieme address.good.until.2009.dec...@justmail.de Edson Tirelli schrieb: when Customer( $custId : id ) DailyOrders( count[$custId] == 1 ) then Btw, this brings me to a new syntax question for the default Drools rule syntax. Is this possible: when m:Map() eval( m.get(type) == Point, $x : m.get(x) ) ... Circle( x == $x ) then ... or, an alternative which may be clearer: when m:Map() eval( m.get(type) == Point ) $x : m.get(x) ... then ... So, what I would like to have is: 1) looking at all Maps which have the value Point under the key type 2) of all those Maps: store in a var what value they have under key x 3) reuse the var, here $x instead of having an expensive lookup over and over again. Is that possible? Or would I have to write my example above as ... c:Circle() eval(c.getX() == m.get(x)) 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 -- 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
[rules-users] how to use xml file instead of java object ?
I remember seeing a sample in jboss-esb sample where they were able to use xpath to query a xml file [sample extract] package com.jboss.soa.esb.routing.cbr #list any import classes here. import org.jboss.soa.esb.message.Message; import org.jboss.soa.esb.message.format.MessageType; expander XPathLanguage.dsl #declare any global variables here global java.util.List destinations; rule Blue Routing Rule using XPATH when xpathEquals /Order/@statusCode, 0 then Log : Blue Team; Destination : blue; end Is it possible to use this approach to use a xml as input to drool vs java object ? Thanks, -Raghav -- View this message in context: http://www.nabble.com/how-to-use-xml-file-instead-of-java-object---tp25029652p25029652.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] (no subject)
Hi, I am new to Drools. Can anyone help me with an example of Drools in jsp/servlets. Thanks, Nilima Rajendra Raichandani Tata Consultancy Services Mailto: nilim...@tcs.com Website: http://www.tcs.com Experience certainty. IT Services Business Solutions Outsourcing =-=-= Notice: The information contained in this e-mail message and/or attachments to it may contain confidential or privileged information. If you are not the intended recipient, any dissemination, use, review, distribution, printing or copying of the information contained in this e-mail message and/or attachments to it are strictly prohibited. If you have received this communication in error, please notify us by reply e-mail or telephone and immediately and permanently delete the message and any attachments. Thank you ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Cannot view Process Definitions in gwt-console
I am trying to deploy drools-guvnor, gwt-console in Tomcat. I am using mysql for persistence. I uploaded the process definitions in drools-guvnor.(I can see them Packages -- defaultPackage -- RuleFlows) However when I try to view them in Processes -- Process Definitions -- Definition List, I cannot see them. Following is from tomcat server log.(with debugging statements that I added.) I placed debug statements in org.drools.guvnor.server.files.PackageDeploymentServlet.doGet method. This method calls org.drools.guvnor.server.files.FileManagerUtils.loadBinaryPackage method. //Following is the debug statement that I placed in org.drools.guvnor.server.files.FileManagerUtils.loadBinaryPackage method. public String loadBinaryPackage(String packageName, String packageVersion, boolean isLatest, OutputStream out) throws IOException { PackageItem item = null; if ( isLatest ) { item = repository.loadPackage( packageName ); System.out.println(FileManagerUtils.loadBinaryPackage() ...); AssetItemIterator ai = item.queryAssets(drools:format='rf', false); for (;ai.hasNext();) { Object o = ai.next(); System.out.println(FileManagerUtils.loadBinaryPackage item = + o.getClass() +:+o); System.out.println(*); } As you can see the servlet returns the rule flow. I also placed some debug statements in org.drools.rule.Package.readExternal method. As you can see when it comes to this method rule flow is empty. Because of this org.drools.integration.console.DroolsFlowCommandDelegate.getProcesses() function returns 0 process definitions. Can somebody help? [2009:08:231 22:08:625:debug] KnowledgeAgent rebuilding KnowledgeBase using ChangeSet [2009:08:231 22:08:625:debug] KnowledgeAgent building resource=[UrlResource path='http://localhost:8081/drools-guvnor/org.drools.guvnor.Guvnor/package/defaultPackage/LATEST'] PackageName: defaultPackage //org.drools.guvnor.server.files.PackageDeploymentServlet.doGet - Begin PackageVersion: LATEST PackageIsLatest: true PackageIsSource: false requestURI: /drools-guvnor/org.drools.guvnor.Guvnor/package/defaultPackage/LATEST test: /drools-guvnor/org.drools.guvnor.Guvnor/package/defaultPackage/LATEST //org.drools.guvnor.server.files.PackageDeploymentServlet.doGet - End FileManagerUtils.loadBinaryPackage() ... // org.drools.guvnor.server.files.FileManagerUtils.loadBinaryPackage - Begin FileManagerUtils.loadBinaryPackage item = class org.drools.repository.AssetItem:Content of rule item named 'testRF': Content: ?xml version=1.0 encoding=UTF-8? process xmlns=http://drools.org/drools-5.0/process; xmlns:xs=http://www.w3.org/2001/XMLSchema-instance; xs:schemaLocation=http://drools.org/drools-5.0/process drools-processes-5.0.xsd type=RuleFlow name=ProjectApprovalProcess id=ProjectApprovalProcess package-name=defaultPackage header variables variable name=project type name=org.drools.process.core.datatype.impl.type.ObjectDataType className=com.yesVin.workflow.project.Project / /variable variable name=status type name=org.drools.process.core.datatype.impl.type.StringDataType / /variable /variables /header nodes start id=1 name=Start x=15 y=11 width=80 height=40 / end id=2 name=End x=206 y=442 width=80 height=40 / humanTask id=3 name=Review Project x=126 y=12 width=80 height=40 .. ... . .. //org.drools.guvnor.server.files.FileManagerUtils.loadBinaryPackage - End Package.readExternal isDroolsStream = true // org.drools.rule.Package.readExternal - Begin Package.readExternal pkg = null dialectRuntimeRegistry = org.drools.rule.dialectruntimeregis...@198046 name = defaultPackage imports = {defaultpackage.*=org.drools.rule.importdeclarat...@d75e0360} staticImports = [] functions = {} factTemplates = {} ruleFlows = {} globals = {} valid = true rules = {} classFieldAccessorStore = org.drools.base.classfieldaccessorst...@34b350 //org.drools.rule.Package.readExternal - End -- View this message in context: http://www.nabble.com/Cannot-view-Process-Definitions-in-gwt-console-tp25056005p25056005.html Sent from the drools - user mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users