Re: [rules-users] Drools and Clojure

2009-08-20 Thread Mark Proctor

André Thieme wrote:

Mark Proctor schrieb:
  

André Thieme wrote:


Mark Proctor schrieb:
  
  

Map( this['c'] == 206 )

That should work, we do support MVEL syntax for maps and arrays - we 
just don't suppor method calls, yet.



Hello Mark. I just tested it and it indeed works for me.
Although as I understand it, this will be compiled into an expression
using eval (or it will even be only interpreted).
So, if that is true it can't bring any performance advantage.
  
  
yes, no performance benefit. As this form of use is a "return value" 
really, it should be possible to index (if we assume that nest objects 
do not change). Although it's a fair bit of work to do this, but 
interesting work - if anyone wants to help out :)



It would be fantastic if there was the same optimization support for
Maps available as it exists for POJOs. Edson gave a great explanation
on how things slow down for cross products.

I thought about one thing:
Could there could maybe be a new attribute, "immutable true" or
something like that, which would signal that the rule writer promises
the engine that only immutable objects are used?
That way my lib could implicitly always set that attribute.

  
It could certainly be done, lots of ways to cook this - from annotation 
on the pojo, type declarations and possibly some annotation on the rule 
or pattern itself. If you want to take a crack at this, you know where 
to find us :)

http://www.jboss.org/drools/irc.html

Mark
  

The syntax is nothing I worry about. In Clojure, which is a Lisp, I have
macros and can remove any obstacles in the syntax I like. It is trivial
to develop new domain specific languages for rules. So, my rule syntax
for Clojure will look very lispy, and each user is free to change and
extend it. I will also allow the RHS to be written in Clojure code, no
Java needed.
  
  

Btw if you are doing "lispy" stuff:
http://blog.athico.com/2008/02/drools-clips.html
http://blog.athico.com/2008/06/drools-clips-progress.html



Ah yes, very interesting.
In principle it is very similar what I do.
With Clojure there is a full featured Lisp on the JVM.
What I do is adding some functions and macros, easy to use, which will
do all the Drools managing and hide it from the user.
It will be simple to add all kinds of syntaxes as soon I am done.
You can have the Jess syntax. Just write a macro and expand it into
mine. It will result in compiled rules code.
So, in some days (when I have time) the project above will be
finished ;-)


  

see "Null-Safe Bean Navigation"
http://mvel.codehaus.org/MVEL+2.0+Property+Navigation



Ah of course, I forgot the null. And MVEL already has the check built
in.
I think I will also implicitly add it.


  

And another interesting thing I noticed:
to both rules I added the line
global String s;
and in the LHS's of both rules I removed the "c" and put s at its place.
Then the first thing I did after creating a session was to
(.setGlobal session "s" "c")

The rule 1 accepted this change. I can use s instead of "c". But there
is still the limitation that I can only insert Maps into the session
which do have the String "c" as key. Otherwise: NPE.
The rule 2 (mvel) however does not accept s as a placeholder. I get:
Exception executing predicate this[s] == 206
[Thrown class org.drools.RuntimeDroolsException]

Any ideas how to get rid of the NPE?
  
  

We'll have to look into this, probably a bug.



Edson confirmed that this is an MVEL problem.
In a different thread KDR may have discovered another one.


André
  


___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Drools and Clojure

2009-08-20 Thread André Thieme
Mark Proctor schrieb:
> 
> André Thieme wrote:
>> Mark Proctor schrieb:
>>   
>>> Map( this['c'] == 206 )
>>>
>>> That should work, we do support MVEL syntax for maps and arrays - we 
>>> just don't suppor method calls, yet.
>>> 
>> Hello Mark. I just tested it and it indeed works for me.
>> Although as I understand it, this will be compiled into an expression
>> using eval (or it will even be only interpreted).
>> So, if that is true it can't bring any performance advantage.
>>   
> yes, no performance benefit. As this form of use is a "return value" 
> really, it should be possible to index (if we assume that nest objects 
> do not change). Although it's a fair bit of work to do this, but 
> interesting work - if anyone wants to help out :)

It would be fantastic if there was the same optimization support for
Maps available as it exists for POJOs. Edson gave a great explanation
on how things slow down for cross products.

I thought about one thing:
Could there could maybe be a new attribute, "immutable true" or
something like that, which would signal that the rule writer promises
the engine that only immutable objects are used?
That way my lib could implicitly always set that attribute.


>> The syntax is nothing I worry about. In Clojure, which is a Lisp, I have
>> macros and can remove any obstacles in the syntax I like. It is trivial
>> to develop new domain specific languages for rules. So, my rule syntax
>> for Clojure will look very lispy, and each user is free to change and
>> extend it. I will also allow the RHS to be written in Clojure code, no
>> Java needed.
>>   
> Btw if you are doing "lispy" stuff:
> http://blog.athico.com/2008/02/drools-clips.html
> http://blog.athico.com/2008/06/drools-clips-progress.html

Ah yes, very interesting.
In principle it is very similar what I do.
With Clojure there is a full featured Lisp on the JVM.
What I do is adding some functions and macros, easy to use, which will
do all the Drools managing and hide it from the user.
It will be simple to add all kinds of syntaxes as soon I am done.
You can have the Jess syntax. Just write a macro and expand it into
mine. It will result in compiled rules code.
So, in some days (when I have time) the project above will be
finished ;-)


> see "Null-Safe Bean Navigation"
> http://mvel.codehaus.org/MVEL+2.0+Property+Navigation

Ah of course, I forgot the null. And MVEL already has the check built
in.
I think I will also implicitly add it.


>> And another interesting thing I noticed:
>> to both rules I added the line
>> global String s;
>> and in the LHS's of both rules I removed the "c" and put s at its place.
>> Then the first thing I did after creating a session was to
>> (.setGlobal session "s" "c")
>>
>> The rule 1 accepted this change. I can use s instead of "c". But there
>> is still the limitation that I can only insert Maps into the session
>> which do have the String "c" as key. Otherwise: NPE.
>> The rule 2 (mvel) however does not accept s as a placeholder. I get:
>> Exception executing predicate this[s] == 206
>> [Thrown class org.drools.RuntimeDroolsException]
>>
>> Any ideas how to get rid of the NPE?
>>   
> We'll have to look into this, probably a bug.

Edson confirmed that this is an MVEL problem.
In a different thread KDR may have discovered another one.


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] Drools and Clojure

2009-08-13 Thread Greg Barton
Well, you never know it performs until you try. :)  See attached project.

$ java -jar target/DroolsMapTest-1.0.jar eval.drl
{bar=0}
{foo=100}
Time: 6607ms

$ java -jar target/DroolsMapTest-1.0.jar mvel.drl
{bar=0}
{foo=100}
Time: 13077ms

So eval ended up being 2x as fast, at least for this micro benchmark.  I guess 
the fact that the "this['foo']" expressions are not indexed, plus the fact that 
they're interpreted mvel, doubles up.  Stick with the eval.

--- On Thu, 8/13/09, André Thieme  
wrote:

> From: André Thieme 
> Subject: Re: [rules-users] Drools and Clojure
> To: "Rules Users List" 
> Date: Thursday, August 13, 2009, 6:29 PM
> With what have you been wrong Greg?
> I understood Marks reply in such a way that the mvel
> dialect allows to
> use Maps without eval. But this is just syntactic sugar.
> When compiled
> or interpreted (I don't know which of those Drools will do
> with mvel
> rules), this will get replaced with an eval under the
> hood.
> So, that means that still the optimizations can't be
> applied.
> Maybe the mvel rule is only interpreted, which would make
> it even slower.
> 
> For me it does not matter much which syntax will be my
> target.
> My Clojure lib will allow to write down rules in
> s-expression
> syntax, and it will compile them (compilation is also
> available at
> runtime) into any syntax Drools accepts.
> Currently my target is the default syntax - that means I
> will
> produce strings that access Maps with eval.
> 
> IF the mvel syntax will result in more performant code
> because it
> makes Drools handle it better without using eval under the
> hood, then
> sure, I can also compile into mvel syntax.
> Although with that I still have the little problem to have
> globals in
> place of literals for Map lookups (see my other mail).
> 
> 
> 
> Greg Barton schrieb:
> > I was wrong. :). See Mark's later email.
> > 
> > GreG
> > 
> > On Aug 13, 2009, at 17:25, André Thieme 
> > 
> wrote:
> > 
> > Greg Barton schrieb:
> > There's no reason why a rete based system couldn't use
> maps as first
> > class objects, but Drools is heavily oriented towards
> POJOS.  Using
> > eval in the way you have is pretty much the way to
> go.
> > 
> > Thanks for confirming that.
> > For now I know that I am doing it right by using eval
> and that this
> > means that rules for typical Clojure objects will not
> benefit from some
> > of the optimizations Drools usually can apply.
> > Maybe it will change in the future.
> > 
> > 
> > As long as type information is accessible (both for
> first class types
> > and their members) you should be able to have the left
> hand side of a
> > rule (the conditions) be as it is now.
> > 
> > I think that if Maps become 1st class objects there
> could be a different
> > Syntax, without using eval.
> > 
> > 
> > If you lobby the devs hard enough and get others on
> your side you may
> > be able to convince them to go in that direction, but
> I doubt it
> > would be possible before version 6 or so, if that
> early.  (And I'm
> > not even sure it's possible.)
> > 
> > At this point it is mostly interesting for me to get
> Drools working with
> > Clojure together and concentrate on correctness. The
> goal is that users
> > of my lib can use do all typical things people do with
> Drools without
> > writing Java code. Everything, including the rules,
> would be written in
> > Clojure.
> > But of course it would be very interesting if the devs
> could indeed have
> > Clojure in mind. I don't know how reusable the
> existing code is, for
> > using Maps without the need for eval and with having
> the respective
> > performance advantages.
> > I understand that the looup of the value for a given
> key can not be
> > optimized away. On my hardware get() is limited to
> "only" 1000 calls
> > per msec and core. Reading a field from a POJO is
> faster.
> > If I understand it correctly then the "problem" with
> eval is that it
> > needs to be executed each time, and no clever caching
> can be done.
> > So, eliminating that by having Maps being 1st class is
> what sounds
> > interesting.
> > When I refer to Maps and Clojure, then I talk about
> Maps having only
> > very few key/value pairs, just like POJOs, and being
> immutable.
> > This immutability may even be very helpful for
> optimization. It is
> > guaranteed that a given object will never change.
> > 
> > I hope the devs will find it okay if I make some
> concrete suggestions
> > in the coming weeks.
> > 
> > 
> > Sunny greetings,
> > 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
>


  

DroolsMap.tar.gz
Description: GNU Zip compressed data
___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Drools and Clojure

2009-08-13 Thread Mark Proctor


André Thieme wrote:

Mark Proctor schrieb:
  

Map( this['c'] == 206 )

That should work, we do support MVEL syntax for maps and arrays - we 
just don't suppor method calls, yet.



Hello Mark. I just tested it and it indeed works for me.
Although as I understand it, this will be compiled into an expression
using eval (or it will even be only interpreted).
So, if that is true it can't bring any performance advantage.
  
yes, no performance benefit. As this form of use is a "return value" 
really, it should be possible to index (if we assume that nest objects 
do not change). Although it's a fair bit of work to do this, but 
interesting work - if anyone wants to help out :)

The syntax is nothing I worry about. In Clojure, which is a Lisp, I have
macros and can remove any obstacles in the syntax I like. It is trivial
to develop new domain specific languages for rules. So, my rule syntax
for Clojure will look very lispy, and each user is free to change and
extend it. I will also allow the RHS to be written in Clojure code, no
Java needed.
  

Btw if you are doing "lispy" stuff:
http://blog.athico.com/2008/02/drools-clips.html
http://blog.athico.com/2008/06/drools-clips-progress.html


But back to your example: I noticed something very interesting:
when I use the MVEL dialect for the Map lookup, then I get no NPE
anymore when I check in a Map which does *not* have the key I test
for.
So, now I have two versions of my rule:

package droolsandclojure;
import java.util.Map;

rule "Clojure test 1"
   when
m:Map()
eval((Integer)m.get("c") == 206)
   then
System.out.println("Match: " + m);
end

and

package droolsandclojure;
import java.util.Map;

rule "Clojure MVEL test 2"
  dialect "mvel"
   when
m:Map( this["c"] == 206 )
   then
System.out.println("Match: " + m);
end


Only one of these two rules is used, not both at the same time.
When I use rule 1 then I can not insert Maps into my session which do
not have a key "c". If I try it and run my code I get a NPE.

When I use rule 2, the MVEL version, this is different. Now I can
insert any Maps and will not get an exception. The rule will simply
just not execute the RHS.

How can rule 1 be changed so that it will not put a constraint on the
objects which are allowed to go into the session without throwing a NPE?

  

see "Null-Safe Bean Navigation"
http://mvel.codehaus.org/MVEL+2.0+Property+Navigation

And another interesting thing I noticed:
to both rules I added the line
global String s;
and in the LHS's of both rules I removed the "c" and put s at its place.
Then the first thing I did after creating a session was to
(.setGlobal session "s" "c")

The rule 1 accepted this change. I can use s instead of "c". But there
is still the limitation that I can only insert Maps into the session
which do have the String "c" as key. Otherwise: NPE.
The rule 2 (mvel) however does not accept s as a placeholder. I get:
Exception executing predicate this[s] == 206
[Thrown class org.drools.RuntimeDroolsException]

Any ideas how to get rid of the NPE?
  

We'll have to look into this, probably a bug.

Mark

___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Drools and Clojure

2009-08-13 Thread André Thieme
With what have you been wrong Greg?
I understood Marks reply in such a way that the mvel dialect allows to
use Maps without eval. But this is just syntactic sugar. When compiled
or interpreted (I don't know which of those Drools will do with mvel
rules), this will get replaced with an eval under the hood.
So, that means that still the optimizations can't be applied.
Maybe the mvel rule is only interpreted, which would make it even slower.

For me it does not matter much which syntax will be my target.
My Clojure lib will allow to write down rules in s-expression
syntax, and it will compile them (compilation is also available at
runtime) into any syntax Drools accepts.
Currently my target is the default syntax - that means I will
produce strings that access Maps with eval.

IF the mvel syntax will result in more performant code because it
makes Drools handle it better without using eval under the hood, then
sure, I can also compile into mvel syntax.
Although with that I still have the little problem to have globals in
place of literals for Map lookups (see my other mail).



Greg Barton schrieb:
> I was wrong. :). See Mark's later email.
> 
> GreG
> 
> On Aug 13, 2009, at 17:25, André Thieme 
>  wrote:
> 
> Greg Barton schrieb:
> There's no reason why a rete based system couldn't use maps as first
> class objects, but Drools is heavily oriented towards POJOS.  Using
> eval in the way you have is pretty much the way to go.
> 
> Thanks for confirming that.
> For now I know that I am doing it right by using eval and that this
> means that rules for typical Clojure objects will not benefit from some
> of the optimizations Drools usually can apply.
> Maybe it will change in the future.
> 
> 
> As long as type information is accessible (both for first class types
> and their members) you should be able to have the left hand side of a
> rule (the conditions) be as it is now.
> 
> I think that if Maps become 1st class objects there could be a different
> Syntax, without using eval.
> 
> 
> If you lobby the devs hard enough and get others on your side you may
> be able to convince them to go in that direction, but I doubt it
> would be possible before version 6 or so, if that early.  (And I'm
> not even sure it's possible.)
> 
> At this point it is mostly interesting for me to get Drools working with
> Clojure together and concentrate on correctness. The goal is that users
> of my lib can use do all typical things people do with Drools without
> writing Java code. Everything, including the rules, would be written in
> Clojure.
> But of course it would be very interesting if the devs could indeed have
> Clojure in mind. I don't know how reusable the existing code is, for
> using Maps without the need for eval and with having the respective
> performance advantages.
> I understand that the looup of the value for a given key can not be
> optimized away. On my hardware get() is limited to "only" 1000 calls
> per msec and core. Reading a field from a POJO is faster.
> If I understand it correctly then the "problem" with eval is that it
> needs to be executed each time, and no clever caching can be done.
> So, eliminating that by having Maps being 1st class is what sounds
> interesting.
> When I refer to Maps and Clojure, then I talk about Maps having only
> very few key/value pairs, just like POJOs, and being immutable.
> This immutability may even be very helpful for optimization. It is
> guaranteed that a given object will never change.
> 
> I hope the devs will find it okay if I make some concrete suggestions
> in the coming weeks.
> 
> 
> Sunny greetings,
> 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] Drools and Clojure

2009-08-13 Thread André Thieme
Mark Proctor schrieb:
> Map( this['c'] == 206 )
> 
> That should work, we do support MVEL syntax for maps and arrays - we 
> just don't suppor method calls, yet.

Hello Mark. I just tested it and it indeed works for me.
Although as I understand it, this will be compiled into an expression
using eval (or it will even be only interpreted).
So, if that is true it can't bring any performance advantage.

The syntax is nothing I worry about. In Clojure, which is a Lisp, I have
macros and can remove any obstacles in the syntax I like. It is trivial
to develop new domain specific languages for rules. So, my rule syntax
for Clojure will look very lispy, and each user is free to change and
extend it. I will also allow the RHS to be written in Clojure code, no
Java needed.


But back to your example: I noticed something very interesting:
when I use the MVEL dialect for the Map lookup, then I get no NPE
anymore when I check in a Map which does *not* have the key I test
for.
So, now I have two versions of my rule:

package droolsandclojure;
import java.util.Map;

rule "Clojure test 1"
   when
m:Map()
eval((Integer)m.get("c") == 206)
   then
System.out.println("Match: " + m);
end

and

package droolsandclojure;
import java.util.Map;

rule "Clojure MVEL test 2"
  dialect "mvel"
   when
m:Map( this["c"] == 206 )
   then
System.out.println("Match: " + m);
end


Only one of these two rules is used, not both at the same time.
When I use rule 1 then I can not insert Maps into my session which do
not have a key "c". If I try it and run my code I get a NPE.

When I use rule 2, the MVEL version, this is different. Now I can
insert any Maps and will not get an exception. The rule will simply
just not execute the RHS.

How can rule 1 be changed so that it will not put a constraint on the
objects which are allowed to go into the session without throwing a NPE?


And another interesting thing I noticed:
to both rules I added the line
global String s;
and in the LHS's of both rules I removed the "c" and put s at its place.
Then the first thing I did after creating a session was to
(.setGlobal session "s" "c")

The rule 1 accepted this change. I can use s instead of "c". But there
is still the limitation that I can only insert Maps into the session
which do have the String "c" as key. Otherwise: NPE.
The rule 2 (mvel) however does not accept s as a placeholder. I get:
Exception executing predicate this[s] == 206
[Thrown class org.drools.RuntimeDroolsException]

Any ideas how to get rid of the NPE?
-- 
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] Drools and Clojure

2009-08-13 Thread Greg Barton
I was wrong. :). See Mark's later email.

GreG

On Aug 13, 2009, at 17:25, André Thieme 
 wrote:

Greg Barton schrieb:
There's no reason why a rete based system couldn't use maps as first
class objects, but Drools is heavily oriented towards POJOS.  Using
eval in the way you have is pretty much the way to go.

Thanks for confirming that.
For now I know that I am doing it right by using eval and that this
means that rules for typical Clojure objects will not benefit from some
of the optimizations Drools usually can apply.
Maybe it will change in the future.


As long as type information is accessible (both for first class types
and their members) you should be able to have the left hand side of a
rule (the conditions) be as it is now.

I think that if Maps become 1st class objects there could be a different
Syntax, without using eval.


If you lobby the devs hard enough and get others on your side you may
be able to convince them to go in that direction, but I doubt it
would be possible before version 6 or so, if that early.  (And I'm
not even sure it's possible.)

At this point it is mostly interesting for me to get Drools working with
Clojure together and concentrate on correctness. The goal is that users
of my lib can use do all typical things people do with Drools without
writing Java code. Everything, including the rules, would be written in
Clojure.
But of course it would be very interesting if the devs could indeed have
Clojure in mind. I don't know how reusable the existing code is, for
using Maps without the need for eval and with having the respective
performance advantages.
I understand that the looup of the value for a given key can not be
optimized away. On my hardware get() is limited to "only" 1000 calls
per msec and core. Reading a field from a POJO is faster.
If I understand it correctly then the "problem" with eval is that it
needs to be executed each time, and no clever caching can be done.
So, eliminating that by having Maps being 1st class is what sounds
interesting.
When I refer to Maps and Clojure, then I talk about Maps having only
very few key/value pairs, just like POJOs, and being immutable.
This immutability may even be very helpful for optimization. It is
guaranteed that a given object will never change.

I hope the devs will find it okay if I make some concrete suggestions
in the coming weeks.


Sunny greetings,
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



  

___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Drools and Clojure

2009-08-13 Thread André Thieme
Greg Barton schrieb:
> There's no reason why a rete based system couldn't use maps as first
> class objects, but Drools is heavily oriented towards POJOS.  Using
> eval in the way you have is pretty much the way to go.

Thanks for confirming that.
For now I know that I am doing it right by using eval and that this
means that rules for typical Clojure objects will not benefit from some
of the optimizations Drools usually can apply.
Maybe it will change in the future.


> As long as type information is accessible (both for first class types
> and their members) you should be able to have the left hand side of a
> rule (the conditions) be as it is now.

I think that if Maps become 1st class objects there could be a different
Syntax, without using eval.


> If you lobby the devs hard enough and get others on your side you may
> be able to convince them to go in that direction, but I doubt it
> would be possible before version 6 or so, if that early.  (And I'm
> not even sure it's possible.)

At this point it is mostly interesting for me to get Drools working with
Clojure together and concentrate on correctness. The goal is that users
of my lib can use do all typical things people do with Drools without
writing Java code. Everything, including the rules, would be written in
Clojure.
But of course it would be very interesting if the devs could indeed have
Clojure in mind. I don't know how reusable the existing code is, for
using Maps without the need for eval and with having the respective
performance advantages.
I understand that the looup of the value for a given key can not be
optimized away. On my hardware get() is limited to "only" 1000 calls
per msec and core. Reading a field from a POJO is faster.
If I understand it correctly then the "problem" with eval is that it
needs to be executed each time, and no clever caching can be done.
So, eliminating that by having Maps being 1st class is what sounds
interesting.
When I refer to Maps and Clojure, then I talk about Maps having only
very few key/value pairs, just like POJOs, and being immutable.
This immutability may even be very helpful for optimization. It is
guaranteed that a given object will never change.

I hope the devs will find it okay if I make some concrete suggestions
in the coming weeks.


Sunny greetings,
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] Drools and Clojure

2009-08-11 Thread Greg Barton

Golly, that's just too easy. :P

--- On Tue, 8/11/09, Mark Proctor  wrote:

> From: Mark Proctor 
> Subject: Re: [rules-users] Drools and Clojure
> To: "Rules Users List" 
> Date: Tuesday, August 11, 2009, 11:09 PM
> Map( this['c'] == 206 )
> 
> That should work, we do support MVEL syntax for maps and
> arrays - we 
> just don't suppor method calls, yet.


  
___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Drools and Clojure

2009-08-11 Thread Mark Proctor
Map( this['c'] == 206 )

That should work, we do support MVEL syntax for maps and arrays - we 
just don't suppor method calls, yet.

Mark
André Thieme wrote:
> My previous mail did not really have any resonance, which is probably
> due to the fact that I put the word "Clojure" into the subject. Some of
> you may not know that Clojure is a programming language which compiles
> to Java byte code and which can use all Java classes and which can
> itself also produce classes which are then usable in Java.
> I hope this time some people will answer :-)
> I would like to see some comments about the eval+Maps issue and a tip
> how I can have rules which are not constraints at the same time about
> what can be inserted into a session.
>
>
> Currently I am writing a lib which will make Drools usable from within
> the Clojure programming language. That is good for both, Drools and
> Clojure. That way Drools gets more users and more Clojure users can use
> that powerful system.
>
> At the end of this mail you will find my original one that I sent some
> days ago which got no answer. By now I found out the answer myself.
> My question was if I can write rules which will fire when some specific
> key/value pairs are set in a HashMap. And yes, I was able to do this via
> eval.
>
> Is there really no other way than using eval?
> The disadvantage seems to be that Drools can not do optimizations over
> evals, but needs to execute that code each time.
> In Clojure it is typical to use Maps instead of POJOs. That would mean
> that Clojure users either have to do non-idiomatic programming, or
> accept that their rules will be slower.
> Although in principle maps and class instances are equivalent. POJOs are
> also maps. They map a key, the field of the class, to a value. POJOs
> have one implicit field, which is their type.
> We could have a
> class Person {
>String name;
>int age;
>...
> }
> or a Map with just three fields: name, age and type.
> In the type slot we could store the string "Person".
> Clojure Maps are immutable which should allow even more optimizations
> than we can have in Drools from POJOs.
> Anyway, here is a rule that I currently use:
>
> package droolsandclojure;
> import clojure.lang.APersistentMap;
>
> rule "Clojure test 1"
>   when
>m:APersistentMap()
>eval((Integer)m.get("c") == 206)
>   then
>System.out.println("Match: " + m);
> end
>
> and in my Clojure program I create a stateful session object and then
> (.insert session {"a" 1, "b" 2, "c" 3})
> (.insert session {"a" 1, "b" 2, "c" 206})
> which inserts two maps into the session object.
> When I then (.fireAllRules session) then it prints out
> Match: {"a" 1, "b" 2, "c" 206}
> as expected.
> One thing is strange though: I can not insert Maps which don't have a
> key "c" - I get a NullPointerException.
> It seems that I set a constraint of which things can go into a session
> instead of having a rule which fires only for those Maps that come with
> the right key/value pairs. Btw, this also happens when I use a
> java.util.HashMap instead of the Clojure one.
>
> The rule then looks like:
> package droolsandclojure;
> import java.util.Map;
>
> rule "Clojure test 2"
>   when
>m:Map()
>eval((Integer)m.get("c") == 206)
>   then
>System.out.println("Match: " + m);
> end
>
> And I do
> (let [map (new java.util.HashMap)]
>(.put map "a" 10)
>(.put map "b" 20)
>(.put map "c" 206)
>...
>(.insert session map)
>...)
>
> which then prints:
> Match: {b=20, c=206, a=10}
> But if I don't (.put map "c" 206) but instead (.put map "d" 206) then I
> get the NPE.
>
> Here my earlier original mail which you can safely ignore.
>
>
> Greetings,
> André
>
>
>
>
> André Thieme schrieb:
>   
>> Hello group!
>>
>> I am a Clojure user and would like to look into using Drools with it.
>>  From Clojure I can use all Java classes and call all methods. So,
>> instantiating a KnowledgeBase, KnowledgePackages or a KBFactory is no
>> problem, and calling the respective methods, to get the system started,
>> or insert facts into a session, dispose it and fireAllRules is also
>> fine.
>>
>> It is just that in Clojure one typically does not use POJOs.
>> The most typical data structures used are: hashmaps, vectors, structs,
>> lists, structuremaps and sets (in no particular order).
>> Those are persistent and "concurrency ready" Clojure DSs, and btw, also
>> usable from Java directly.
>>
>> Now the basic Drools examples I saw all work with POJOs.
>> They were mostly comparisons of native typed fields in a class.
>> I however would be interested to compare different qualities of key/
>> value pairs in a hashmap, or compare structs with each other.
>> Comparing structuremaps is maybe what comes closest to the POJO examples.
>> For example, we may have a struct (defstruct person :name :age :type)
>> and store it's instances in a vector. And we would also insert it into
>> our Drools session object:
>> (doseq [p all-persons] (.inser

Re: [rules-users] Drools and Clojure

2009-08-11 Thread Greg Barton

There's no reason why a rete based system couldn't use maps as first class 
objects, but Drools is heavily oriented towards POJOS.  Using eval in the way 
you have is pretty much the way to go.

That being said, a possible direction for Drools might be the way the 
object-relational mapper Hibernate handles things: tuplizers.  When you create 
a Hibernate session you can specify how you want it to instantiate the data 
mapped in the database.  There are three built in tuplizers: 
Dom4jEntityTuplizer, DynamicMapEntityTuplizer, and PojoEntityTuplizer.  (And 
you can create custom ones.)  

As long as type information is accessible (both for first class types and their 
members) you should be able to have the left hand side of a rule (the 
conditions) be as it is now.  The right hand side is another story entirely, as 
Drools does no processing on it whatsoever.  Creating new working memory 
objects could not be generic, and neither would modification of existing 
objects.  If you did want to make it generic, you would lose the full power of 
java by handing working memory object creation and modification over to Drools. 
 In my experience when systems try to take on that responsibility they don't do 
it as well, or as flexibly, as java does.

If you lobby the devs hard enough and get others on your side you may be able 
to convince them to go in that direction, but I doubt it would be possible 
before version 6 or so, if that early.  (And I'm not even sure it's possible.)

--- On Tue, 8/11/09, André Thieme  
wrote:

> From: André Thieme 
> Subject: [rules-users] Drools and Clojure
> To: "Rules Users List" 
> Date: Tuesday, August 11, 2009, 5:01 PM
> My previous mail did not really have
> any resonance, which is probably
> due to the fact that I put the word "Clojure" into the
> subject. Some of
> you may not know that Clojure is a programming language
> which compiles
> to Java byte code and which can use all Java classes and
> which can
> itself also produce classes which are then usable in Java.
> I hope this time some people will answer :-)
> I would like to see some comments about the eval+Maps issue
> and a tip
> how I can have rules which are not constraints at the same
> time about
> what can be inserted into a session.
> 
> 
> Currently I am writing a lib which will make Drools usable
> from within
> the Clojure programming language. That is good for both,
> Drools and
> Clojure. That way Drools gets more users and more Clojure
> users can use
> that powerful system.
> 
> At the end of this mail you will find my original one that
> I sent some
> days ago which got no answer. By now I found out the answer
> myself.
> My question was if I can write rules which will fire when
> some specific
> key/value pairs are set in a HashMap. And yes, I was able
> to do this via
> eval.
> 
> Is there really no other way than using eval?
> The disadvantage seems to be that Drools can not do
> optimizations over
> evals, but needs to execute that code each time.
> In Clojure it is typical to use Maps instead of POJOs. That
> would mean
> that Clojure users either have to do non-idiomatic
> programming, or
> accept that their rules will be slower.
> Although in principle maps and class instances are
> equivalent. POJOs are
> also maps. They map a key, the field of the class, to a
> value. POJOs
> have one implicit field, which is their type.
> We could have a
> class Person {
>    String name;
>    int age;
>    ...
> }
> or a Map with just three fields: name, age and type.
> In the type slot we could store the string "Person".
> Clojure Maps are immutable which should allow even more
> optimizations
> than we can have in Drools from POJOs.
> Anyway, here is a rule that I currently use:
> 
> package droolsandclojure;
> import clojure.lang.APersistentMap;
> 
> rule "Clojure test 1"
>   when
>    m:APersistentMap()
>    eval((Integer)m.get("c") == 206)
>   then
>    System.out.println("Match: " + m);
> end
> 
> and in my Clojure program I create a stateful session
> object and then
> (.insert session {"a" 1, "b" 2, "c" 3})
> (.insert session {"a" 1, "b" 2, "c" 206})
> which inserts two maps into the session object.
> When I then (.fireAllRules session) then it prints out
> Match: {"a" 1, "b" 2, "c" 206}
> as expected.
> One thing is strange though: I can not insert Maps which
> don't have a
> key "c" - I get a NullPointerException.
> It seems that I set a constraint of which things can go
> into a session
> instead of having a rule which fires only for 

[rules-users] Drools and Clojure

2009-08-11 Thread André Thieme
My previous mail did not really have any resonance, which is probably
due to the fact that I put the word "Clojure" into the subject. Some of
you may not know that Clojure is a programming language which compiles
to Java byte code and which can use all Java classes and which can
itself also produce classes which are then usable in Java.
I hope this time some people will answer :-)
I would like to see some comments about the eval+Maps issue and a tip
how I can have rules which are not constraints at the same time about
what can be inserted into a session.


Currently I am writing a lib which will make Drools usable from within
the Clojure programming language. That is good for both, Drools and
Clojure. That way Drools gets more users and more Clojure users can use
that powerful system.

At the end of this mail you will find my original one that I sent some
days ago which got no answer. By now I found out the answer myself.
My question was if I can write rules which will fire when some specific
key/value pairs are set in a HashMap. And yes, I was able to do this via
eval.

Is there really no other way than using eval?
The disadvantage seems to be that Drools can not do optimizations over
evals, but needs to execute that code each time.
In Clojure it is typical to use Maps instead of POJOs. That would mean
that Clojure users either have to do non-idiomatic programming, or
accept that their rules will be slower.
Although in principle maps and class instances are equivalent. POJOs are
also maps. They map a key, the field of the class, to a value. POJOs
have one implicit field, which is their type.
We could have a
class Person {
   String name;
   int age;
   ...
}
or a Map with just three fields: name, age and type.
In the type slot we could store the string "Person".
Clojure Maps are immutable which should allow even more optimizations
than we can have in Drools from POJOs.
Anyway, here is a rule that I currently use:

package droolsandclojure;
import clojure.lang.APersistentMap;

rule "Clojure test 1"
  when
   m:APersistentMap()
   eval((Integer)m.get("c") == 206)
  then
   System.out.println("Match: " + m);
end

and in my Clojure program I create a stateful session object and then
(.insert session {"a" 1, "b" 2, "c" 3})
(.insert session {"a" 1, "b" 2, "c" 206})
which inserts two maps into the session object.
When I then (.fireAllRules session) then it prints out
Match: {"a" 1, "b" 2, "c" 206}
as expected.
One thing is strange though: I can not insert Maps which don't have a
key "c" - I get a NullPointerException.
It seems that I set a constraint of which things can go into a session
instead of having a rule which fires only for those Maps that come with
the right key/value pairs. Btw, this also happens when I use a
java.util.HashMap instead of the Clojure one.

The rule then looks like:
package droolsandclojure;
import java.util.Map;

rule "Clojure test 2"
  when
   m:Map()
   eval((Integer)m.get("c") == 206)
  then
   System.out.println("Match: " + m);
end

And I do
(let [map (new java.util.HashMap)]
   (.put map "a" 10)
   (.put map "b" 20)
   (.put map "c" 206)
   ...
   (.insert session map)
   ...)

which then prints:
Match: {b=20, c=206, a=10}
But if I don't (.put map "c" 206) but instead (.put map "d" 206) then I
get the NPE.

Here my earlier original mail which you can safely ignore.


Greetings,
André




André Thieme schrieb:
> Hello group!
> 
> I am a Clojure user and would like to look into using Drools with it.
>  From Clojure I can use all Java classes and call all methods. So,
> instantiating a KnowledgeBase, KnowledgePackages or a KBFactory is no
> problem, and calling the respective methods, to get the system started,
> or insert facts into a session, dispose it and fireAllRules is also
> fine.
> 
> It is just that in Clojure one typically does not use POJOs.
> The most typical data structures used are: hashmaps, vectors, structs,
> lists, structuremaps and sets (in no particular order).
> Those are persistent and "concurrency ready" Clojure DSs, and btw, also
> usable from Java directly.
> 
> Now the basic Drools examples I saw all work with POJOs.
> They were mostly comparisons of native typed fields in a class.
> I however would be interested to compare different qualities of key/
> value pairs in a hashmap, or compare structs with each other.
> Comparing structuremaps is maybe what comes closest to the POJO examples.
> For example, we may have a struct (defstruct person :name :age :type)
> and store it's instances in a vector. And we would also insert it into
> our Drools session object:
> (doseq [p all-persons] (.insert session p))
> which would correspond roughly to
> for (Person p : allPersons) { session.insert(p); }
> Only that "person" is a map, not a class.
> Well, of course it is also an object and under the hood a class, a
> java.util.Map even - but I mean that unlike POJOs the key/value pairs
> are stored differently (fields in classes are also just key/value pairs).
> 
> So, i

[rules-users] Drools and Clojure (maps as facts)

2009-07-31 Thread André Thieme
Hello group!

I am a Clojure user and would like to look into using Drools with it.
 From Clojure I can use all Java classes and call all methods. So,
instantiating a KnowledgeBase, KnowledgePackages or a KBFactory is no
problem, and calling the respective methods, to get the system started,
or insert facts into a session, dispose it and fireAllRules is also
fine.

It is just that in Clojure one typically does not use POJOs.
The most typical data structures used are: hashmaps, vectors, structs,
lists, structuremaps and sets (in no particular order).
Those are persistent and "concurrency ready" Clojure DSs, and btw, also
usable from Java directly.

Now the basic Drools examples I saw all work with POJOs.
They were mostly comparisons of native typed fields in a class.
I however would be interested to compare different qualities of key/
value pairs in a hashmap, or compare structs with each other.
Comparing structuremaps is maybe what comes closest to the POJO examples.
For example, we may have a struct (defstruct person :name :age :type)
and store it's instances in a vector. And we would also insert it into
our Drools session object:
(doseq [p all-persons] (.insert session p))
which would correspond roughly to
for (Person p : allPersons) { session.insert(p); }
Only that "person" is a map, not a class.
Well, of course it is also an object and under the hood a class, a
java.util.Map even - but I mean that unlike POJOs the key/value pairs
are stored differently (fields in classes are also just key/value pairs).

So, is there a way to insert maps (let it be java.util.HashMaps for
example) and also to reason about them? I won't care if the syntax
for that is complicated. As Clojure is a Lisp I would just write a
little macro and have a very nice and readable syntax (probably a bit
similar to the one of Jess or Lisa).
Instead of looking at all instances of the type Person AND then have
their age compared, I would look at all maps/structs which have a key
:type with the value :person AND then compare the value of their :age
key with a number, such as:
(rule "example person rule, matching non-adults"
   :when (= :type :person)
 (< :age 18)
   :then
 (println "No service for minors."))

In Java terms it would mean that we insert several instances of
java.util.HashMap, all having the k/v pairs for name, age and type.
HashMap hm = new HashMap();
hm.put("name", someName);
hm.put("age", someAge);
hm.put("type", "person");
session.insert(hm);

Is that in principle possible with Drools 5?


Sunny greetings,
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