Re: [rules-users] Maps in Drools

2009-08-21 Thread André Thieme
Edson Tirelli schrieb:
> 
> 
> 2009/8/20 André Thieme  >
> 
> Would there not be an addition to the syntax needed, for the default
> rule language? For mvel it would not require a change I guess.
> 
> 
> No, as I mentioned to you, the idea is for the DRL to remain the same, 
> so that the rules author does not have to worry about what the IT guys 
> are doing with the domain model. So, the rules author would write:
> 
> Customer( name == "bob" )
> 
> The IT guy would simply use a configuration to tell the engine: this 
> object type uses a map format, that one is a POJO, that other is an XML 
> entity, etc.
> For instance, if he wants to do that in DRL (he could also use API, or 
> conf files), he could do:
> 
> declare Customer
> @format( map )
> end
> 
> declare Order
> @format( pojo )
> end
> 
> So, we have a clear distinction between the technical aspects and the 
> business aspects of the application.

Ah okay, that makes sense and sounds very good!
So, when Maps become first class not the rules will introduce a new
syntax, but intead we would add some declarations.
The only two challenges I see with that is:
1. to allow the keys to be any object and not just only strings.
2. differentiate between fields of the Maps and keys

Point 1.:
Your example  Customer( name == "bob" )  currently is expressed as:
$m : Map(eval($m.get("type" == "Customer")) &&
  eval($m.get("name") == "bob"))
right?
In the declaration for Customer above one would probably have to specify
that for a Map being a Customer depends on the key "type".
But what would  Customer( name == "bob" ) look like if name was not a
String but some other Object?
This info should go into the declare part, yes?


Point 2.:
in your other reply you gave the example:
Map( this["type"] == "Point", $x : this["x"], size == 5 )

Projected on the  Customer( name == "bob" )  example we would need to
differentiate, in Java terms, between:
map.get("size") == 5and   map.size() == 5
So   Customer(name=="Bob" && size==5)   needs to be clear.



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

Yes, it would be similar like that.
What I first do is to write a general macro named "rule" which should
be able to express everything that currently is possible in Drools.
On top of that macro I will define some more, for exmaple there could be
a macro "map-rule" which is specialized on maps.
This can get even more specialized, but in the end all those macros will
expand into the general one, and the general one will generate a
string S which contains all rules and then do a
ResourceFactory.newByteArrayResource(S.getBytes("utf-8")) to get the
rules into Drools, which will from then on continue.

And the way as you suggest it, to let the Drools syntax always be the
same, it may even be easier for me to write my lib. Good :)


> Hmm, but the MVEL syntax can not magically eliminate the eval. Under the
> hood the map accesses will still be inside an eval. Marc confirmed that
> a few days ago.
> MVEL only hides this from the user. This is what I will also do.
> But under the hood it will become
> 
>   $a:Map()
>   $b:Map()
>   eval( $a.get("type") == "Customer" )
>   eval( $b.get("type") == "DailyOrders" )
> 
> 
> Here I think we have other misunderstanding.  I will try to explain, but
> ideally you need to learn a bit about the Rete algorithm to see the 
> whole picture.

Yes, I will read soon (I hope) Chapter 12 of my Drools book,
by Michal Bali.



> There are 2 types of eval(). Inline eval() and top level eval().

Ah, I see, I didn't know that.


> What you wrote above is a top level eval, meaning it will become 
> a node in the rete network. So your example above generates an 
> "execution plan" (making an analogy with SQL) that will get all Maps in 
> the working memory, join them in tuples size 2, and then test each tuple 
> for the 2 evals. So, you see why this will generate C(n,2) partial 
> matches, while C(n,2) as we know is n!/(n-2)!, what is really bad for 
> growing "n".

Very good, now I understand what you mean. Thanks for the sql analogy.


> Now, the same thing could be written using inline evals as:
> 
> $a:Map( eval( $a.get("type") == "Customer" ) )
> $b:Map( eval( $b.get("type") == "DailyOrders" ) )

Excellent, this is very helpful. I just tried this out and was also
successful with it. Now I can have my code generating alpha constraints
without having to use MVEL.


>   In this case, the inline eval() will generate an alpha constraint in 
> the 

Re: [rules-users] Maps in Drools

2009-08-21 Thread André Thieme
Edson Tirelli schrieb:
> 
>Andre,
> 
>The misunderstanding here is that the LHS, except for code blocks 
> like "eval", "return value expressions" and "accumulate code blocks", 
> are all "Drools Language". When you use the "dialect" attribute in a 
> rule or package you are telling the compiler what dialect (MVEL or Java) 
> you will use inside these code blocks mentioned previously + the 
> language for the RHS.

Good that you clear that up, thanks.


> In other words:
> 
> Map( this["type"] == "Point", $x : this["x"], size == 5 )

I thought this is only possible when one declares the dialect MVEL.
Now I understand that what you just wrote also results in a valid rule,
even when MVEL is not set.

In your code above you:
1. check if this.get("type").equals("Point")
2. you set $x to the value of this.get("x")
3. check if this.size == 5
where I interpret 3. as calling the size() method of java.util.Map.
Was that right so far?


> Everything you see in the previous expression is "Drools language", 
> does not matter if you set the dialect to java or mvel in the rule. It 
> happens that Drools uses the same map syntax as MVEL (and a lot of other 
> scripting languages). Also, we know, that drools implementation will 
> resolve the first 2 above expressions in MVEL behind the scenes, and the 
> 3rd will be resolved nativelly, but that is not something users should 
> have to worry about, since they are writing it in "Drools Language".

Yes, I understand.
Only with the middle part I still have some problems.
As you used it,   $x : this["x"]   it works for me.
A minor issue I have with this, but we can ignore that for now, is, that
this will be interpreted.
The real problem for me is: it only works when between the brackets
there is a literal string.
I however can't do that, because my lib should support the general case,
where between the brackets there could be any type of object (which I
would pass in via a global var).


> If they write an eval, THEN they need to differentiate between MVEL 
> and Java according to the chosen dialect.
> 
> rule xyz
>dialect "mvel"
> when
>eval( ...here you write MVEL code... )
> then
>// here you write MVEL code
> end
> 
> rule xyz2
>dialect "java"
> when
>eval( ...here you write JAVA code... )
> then
>// here you write JAVA code
> end

Very good, thanks again for clearing this up.


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


Re: [rules-users] Maps in Drools

2009-08-21 Thread Edson Tirelli
2009/8/20 André Thieme 

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


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

Customer( name == "bob" )

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

declare Customer
@format( map )
end

declare Order
@format( pojo )
end

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

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


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


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

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

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

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

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


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

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

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


Re: [rules-users] Maps in Drools

2009-08-21 Thread Edson Tirelli
   Andre,

   The misunderstanding here is that the LHS, except for code blocks like
"eval", "return value expressions" and "accumulate code blocks", are all
"Drools Language". When you use the "dialect" attribute in a rule or package
you are telling the compiler what dialect (MVEL or Java) you will use inside
these code blocks mentioned previously + the language for the RHS.

In other words:

Map( this["type"] == "Point", $x : this["x"], size == 5 )

Everything you see in the previous expression is "Drools language", does
not matter if you set the dialect to java or mvel in the rule. It happens
that Drools uses the same map syntax as MVEL (and a lot of other scripting
languages). Also, we know, that drools implementation will resolve the first
2 above expressions in MVEL behind the scenes, and the 3rd will be resolved
nativelly, but that is not something users should have to worry about, since
they are writing it in "Drools Language".

If they write an eval, THEN they need to differentiate between MVEL and
Java according to the chosen dialect.

rule xyz
   dialect "mvel"
when
   eval( ...here you write MVEL code... )
then
   // here you write MVEL code
end

rule xyz2
   dialect "java"
when
   eval( ...here you write JAVA code... )
then
   // here you write JAVA code
end

[]s
Edson

2009/8/20 André Thieme 

> Edson Tirelli schrieb:
> >
> >ooops... correct version:
> >
> > when
> >Map( this["type"] == "Point", $x : this["x"] )
> >Map( this["type"] == "Circle", this["x"] == $x )
> > then
> > end
>
> Okay, so in the mvel syntax this is possible.
> Can this also be achieved in the default rule syntax, without mvel?
>
> The mvel syntax needs to be interpreted at runtime, so my Clojure lib
> will have to output rules in Drools' native rule language.
>
> What interests me most is that first part:
> Map( this["type"] == "Point", $x : this["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
___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Maps in Drools

2009-08-20 Thread André Thieme
Mark Proctor schrieb:
>   André Thieme wrote:
>> Edson Tirelli schrieb:
>>   
>>>ooops... correct version:
>>>
>>> when
>>>Map( this["type"] == "Point", $x : this["x"] )
>>>Map( this["type"] == "Circle", this["x"] == $x )
>>> then
>>> end
>>> 
>>   
> We default to MVEL, because it's simple and already contains everything 
> we need for expression evaluation. However it would definitely be 
> possible to implement this natively, effectively "emulating" MVEL - 
> although you need to think what this actual buys? It doesn't buy 
> indexing, as it's not MVEL that is the problem here.

Ah okay, I didn't know that you are now defaulting to MVEL. Pretty much
all the examples I found online and in the books don't use MVEL.

You asked about what it buys: maybe nothing.
I am very new to Drools and still need more experience. But now at least
I *think* that MVEL rules run slower. I read on the official website
that MVEL gets interpreted at runtime.
Some days ago Greg did a little test:
http://www.mail-archive.com/rules-users@lists.jboss.org/msg09839.html

Right now it seems that Drools used from within Clojure would perform
not too well in real world examples, because complex rules will have to
look at 3-5 Maps. That would mean, as Edson explained, a cross product
of all maps, which will reduce performance.
If I don't use mvel I will manually say:

$m1:Map()
$m2:Map()
$m3:Map()
$m4:Map()
eval ( $m1.get ...)
eval ( $m2.get ...)

and so on.
In MVEL syntax it *looks* nicer, because I can make constraints directly
by using the this keyword. But as MVEL is nothing but syntactic sugar
over the real thing it will need to do the same when the program is running.
On top of that, MVEL will be interpreted, thus resulting in even slower
execution, although the rules will look more nicely.


Now while I write this I just got a new thought:
when the Drools engine is fed with the rules, it will also have to
compile them, or interpret them at at runtime.
I take a string s and do a s.getBytes("utf-8") and have this as an
argument to ResourceFactory.newByteArrayResource.
This is how I get rules into the Drools engine. It works.
But now my new thought: shouldn't I be able to create new rules by
purely writing Java code?

If that were possible, then I would not compile my Clojure code into
a string of either MVEL dialect or non-MVEL, but instead compile it to
code which will do everything that would have happened if I had used
a user readable string.
Yeah, now that I think about it, then *this* is the right way how I
should do it.
That way I can do anything that Drools allows and not depend on any
dialect. And my code would be compiled into byte code at runtime. No
interpretation at all. Cool :)

Now that I think about it: you could even trivially get a new dialect
then with my library. "dialect Lisp" could be the attribute. That one
would be as easy as mvel, but lispish (= more parens), but it would run
at max speed, because it could be compiled directly into byte code.
And it would be trivial to have a domain specific language with that.

Could you please give me a start for a trivial example?

rule "points"
  when
   Point( x == 0 )
  then
   System.out.println("foobar");
end

where Point would be a
public class Point {
   private int x;
   private int y;
}
plus two getters and a constructor.

The rule "points". If you would not have this as a file on disk or as a
string in ram, but would want to add it with pure Java code, how would
you then do it?


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

2009-08-20 Thread Mark Proctor

André Thieme wrote:

Edson Tirelli schrieb:
  

   ooops... correct version:

when
   Map( this["type"] == "Point", $x : this["x"] )
   Map( this["type"] == "Circle", this["x"] == $x )
then
end



  
We default to MVEL, because it's simple and already contains everything 
we need for expression evaluation. However it would definitely be 
possible to implement this natively, effectively "emulating" MVEL - 
although you need to think what this actual buys? It doesn't buy 
indexing, as it's not MVEL that is the problem here.


Mark

Okay, so in the mvel syntax this is possible.
Can this also be achieved in the default rule syntax, without mvel?

The mvel syntax needs to be interpreted at runtime, so my Clojure lib
will have to output rules in Drools' native rule language.

What interests me most is that first part:
Map( this["type"] == "Point", $x : this["x"] )


André
  


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


Re: [rules-users] Maps in Drools

2009-08-20 Thread André Thieme
Edson Tirelli schrieb:
> 
>  > So, in principle having Maps support in the LHS is not a big challenge?
> 
> No. Just requires developing a set of classes to work with maps. Being 
> brief:
> 
> * Implement: MapObjectType extends ObjectType
> * Implement: MapReadAccessor and MapWriteAccessor
> * Add support to them into the builders (i.e., the actual wiring of the 
> new classes)
> * Test everything... I probably forgot something, since there's been 
> quite some time since I worked on this.

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


>  > Could you please explain this in a bit more detail?
> Lets call |A| the number of A facts in the working memory and |B| the 
> number of B facts (i.e. cardinality). Lets call p(|A|,|B|) the number of 
> partial matches a rule will create given the cardinality of A and B. 
> Imagine your rule is:
> 
> when
>A()
>B()
> then
> 
> This rule creates a join between A() and B() and the number of join 
> attempts will be: p(|A|,|B|) = |A| * |B|
> 
> Now, if instead of representing A and B as different classes you use 
> Maps with the type attribute as you was suggesting:
> 
> $a : Map()
> $b : Map()
> eval( ... )
> 
> The number of partial matches will be: p(|A|,|B|) = (|A|+|B|)! / 
> (|A|+|B|-2)!

Ah yes okay, I see what you mean.
Well, the current situation for me is that I have to do exactly that.
As it is typical for Clojure apps to store data in Maps I need support
for that. So, I want to allow rules like:

(map-rule "Rule name", "type"
   (when
 "Customer" ( $cust-id "id" )
 "DailyOrders" (= 1 (get "count" $cust-id)))
   (then
 (println "match")))

This is semantically exactly the same as in your example, where Customer
and DailyOrders were POJOs, while they are for me Maps.


> Draw the graph for these two functions and you will get the picture. If 
> you have more than 2 patterns, situation gets worst and worst.
> 
> If instead of eval() you use some alpha constraints, things go down to 
> the same level as using different classes:
> 
> $a : Map( this["type"] == "A" )
> $b : Map( this["type"] == "B" )
> 
> The above will result in the same p(|A|,|B|) = |A| * |B| partial matches.

Hmm, but the MVEL syntax can not magically eliminate the eval. Under the
hood the map accesses will still be inside an eval. Marc confirmed that
a few days ago.
MVEL only hides this from the user. This is what I will also do.
But under the hood it will become

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


And the only reason why I need to do it this way is because in its
current version Drools does not support Maps as 1st class objects.
If it would, then the eval would not be needed anymore.
So, for Clojure users (and basically everyone else who stores data
inside Maps, for whatever the reasons may be) it would be so good to
have that support.

You gave a perfect explanation of why this would be a great addition.

The actual rule syntax is not important for me. My lib will hide it,
as MVEL already does now.
But my lib will compile the rules into the fast native rule language.
It won't be interpreted or any slower than hand written rules.
But currently I am forced to produce this cross product, as there is
no direct support for Maps yet.



> 2009/8/19 André Thieme  >
> 
> 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

Re: [rules-users] Maps in Drools

2009-08-20 Thread André Thieme
Edson Tirelli schrieb:
> 
>ooops... correct version:
> 
> when
>Map( this["type"] == "Point", $x : this["x"] )
>Map( this["type"] == "Circle", this["x"] == $x )
> then
> end

Okay, so in the mvel syntax this is possible.
Can this also be achieved in the default rule syntax, without mvel?

The mvel syntax needs to be interpreted at runtime, so my Clojure lib
will have to output rules in Drools' native rule language.

What interests me most is that first part:
Map( this["type"] == "Point", $x : this["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

2009-08-19 Thread Edson Tirelli
> So, in principle having Maps support in the LHS is not a big challenge?

No. Just requires developing a set of classes to work with maps. Being
brief:

* Implement: MapObjectType extends ObjectType
* Implement: MapReadAccessor and MapWriteAccessor
* Add support to them into the builders (i.e., the actual wiring of the new
classes)
* Test everything... I probably forgot something, since there's been quite
some time since I worked on this.

> Could you please explain this in a bit more detail?
Lets call |A| the number of A facts in the working memory and |B| the number
of B facts (i.e. cardinality). Lets call p(|A|,|B|) the number of partial
matches a rule will create given the cardinality of A and B. Imagine your
rule is:

when
   A()
   B()
then

This rule creates a join between A() and B() and the number of join attempts
will be: p(|A|,|B|) = |A| * |B|

Now, if instead of representing A and B as different classes you use Maps
with the type attribute as you was suggesting:

$a : Map()
$b : Map()
eval( ... )

The number of partial matches will be: p(|A|,|B|) = (|A|+|B|)! /
(|A|+|B|-2)!

Draw the graph for these two functions and you will get the picture. If you
have more than 2 patterns, situation gets worst and worst.

If instead of eval() you use some alpha constraints, things go down to the
same level as using different classes:

$a : Map( this["type"] == "A" )
$b : Map( this["type"] == "B" )

The above will result in the same p(|A|,|B|) = |A| * |B| partial matches.

[]s
Edson


2009/8/19 André Thieme 

> 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.l

Re: [rules-users] Maps in Drools

2009-08-19 Thread Edson Tirelli
when
   Map( this["type"] == "Point", $x : this["x"] )
   Map( this["type"] == "Circle", x == $x )
then
end


2009/8/19 André Thieme 

> 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
___
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


Re: [rules-users] Maps in Drools

2009-08-19 Thread Edson Tirelli
   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 

>
> when
>Map( this["type"] == "Point", $x : this["x"] )
>Map( this["type"] == "Circle", x == $x )
> then
> end
>
>
> 2009/8/19 André Thieme 
>
>> 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


Re: [rules-users] Maps in Drools

2009-08-19 Thread André Thieme
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

2009-08-19 Thread Edson Tirelli
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 

> 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" ,
>  "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 

Re: [rules-users] Maps in Drools

2009-08-19 Thread André Thieme
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

2009-08-19 Thread André Thieme
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" ,
  "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 a

Re: [rules-users] Maps in Drools

2009-08-19 Thread KDR

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


Re: [rules-users] Maps in Drools

2009-08-19 Thread Edson Tirelli
"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

2009/8/18 KDR 

>
> Many thanks for your replies André and Edson. For some reason they hadn't
> shown up on my computer before I posted my follow up info.
>
> I'll download the updated jar and cross my fingers!
>
> 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?
>
> André on your point below:
>
> André Thieme-4 wrote:
> >
> > KDR schrieb:
> >> I'd also need to test for null i.e. whether a key/value pair exists for
> a
> >> given String as the key.
> >
> > This seems to be only true when you go the route that I go, namely using
> > the default rule syntax, i.e., eval.
> >
>
> - I don't think I quite follow? If I need to check whether the key/value
> pair exists for a particular String key i.e. whether the get(key) returns
> null, is the only way to do that currently by using the eval?
>
> Cheers and thanks again for the help.
> --
> View this message in context:
> http://www.nabble.com/Maps-in-Drools-tp25031348p25034293.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] Maps in Drools

2009-08-18 Thread KDR

Many thanks for your replies André and Edson. For some reason they hadn't
shown up on my computer before I posted my follow up info.

I'll download the updated jar and cross my fingers! 

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?

André on your point below:

André Thieme-4 wrote:
> 
> KDR schrieb:
>> I'd also need to test for null i.e. whether a key/value pair exists for a
>> given String as the key.
> 
> This seems to be only true when you go the route that I go, namely using
> the default rule syntax, i.e., eval.
> 

- I don't think I quite follow? If I need to check whether the key/value
pair exists for a particular String key i.e. whether the get(key) returns
null, is the only way to do that currently by using the eval?

Cheers and thanks again for the help.
-- 
View this message in context: 
http://www.nabble.com/Maps-in-Drools-tp25031348p25034293.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] Maps in Drools

2009-08-18 Thread KDR

Apologies, I should have given the error message I get with $m: Map(
this[$str] == 1 ) and also with $m: Map( this.$str == 1 ) -
org.drools.RuntimeDroolsException: Exception executing predicate this[$str]
== 1
and lots more lines followed by -
Caused by: [Error: unable to resolve method: java.util.HashMap.$str()
[arglength=0]]


KDR wrote:
> 
> Hi, I'm relatively new to both Java and Drools. I'm trying to figure out
> how to use maps in Drools. I've looked at the thread
> http://www.mail-archive.com/rules-users@lists.jboss.org/msg09802.html
> 
> From what I've read generally it seems best to insert objects directly
> rather than use nested accessors. So I've been experimenting with trying
> to insert a map and then checking stuff in it.
> 
> I set up a simple test map of String to Integer, with just "a" as key and
> 1 as value, and "b" with 2.
> Map map = new HashMap();
> map.put("a", 1);
> map.put("b", 2);
> String a = "a";
>   
> I then inserted the map and also inserted the String a of value "a".
> 
> Here's the test rule, with various things I tried commented out:
> 
> rule "testing maps"
>   dialect "mvel"
>   when
>   $str: String()
>   // $m: Map( this[$str] == 1 ) # error
>   // $m: Map( this.$str == 1 )   # error
>   // $m: Map( this["$str"] == 1 ) # compiles but rule won't fire
>   $m: Map( this["a"] == 1 ) # this works however!
>   then
>   System.out.println($m[$str]); #also works with String and Map 
> objects &
> no conditions
> end
> 
> It obviously doesn't like it when I try to use the String object as the
> key for the map. But it works when I use a String literal as the key. What
> am I doing wrong?
> 
> Does anyone have any suggestions please, or shall I give up and either use
> eval as mentioned in
> http://www.mail-archive.com/rules-users@lists.jboss.org/msg09716.html or
> use the map as a field of another object which I insert instead of the map
> (in fact that was my original plan!)?
> 
> I'd also need to test for null i.e. whether a key/value pair exists for a
> given String as the key.
> 
> Any thoughts would be very much appreciated.
> 
> Many thanks in advance.
> 

-- 
View this message in context: 
http://www.nabble.com/Maps-in-Drools-tp25031348p25031731.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] Maps in Drools

2009-08-18 Thread Edson Tirelli
   Yes, that was a bug that was fixed in newer versions of MVEL. Just update
your MVEL jar to 2.0.12.

   []s
   Edson

2009/8/18 André Thieme 

> KDR schrieb:
> > Hi, I'm relatively new to both Java and Drools. I'm trying to figure out
> how
> > to use maps in Drools. I've looked at the thread
> > http://www.mail-archive.com/rules-users@lists.jboss.org/msg09802.html
> >
> >>From what I've read generally it seems best to insert objects directly
> > rather than use nested accessors. So I've been experimenting with trying
> to
> > insert a map and then checking stuff in it.
> >
> > I set up a simple test map of String to Integer, with just "a" as key and
> 1
> > as value, and "b" with 2.
> > Map map = new HashMap();
> > map.put("a", 1);
> > map.put("b", 2);
> > String a = "a";
> >
> > I then inserted the map and also inserted the String a of value "a".
> >
> > Here's the test rule, with various things I tried commented out:
> >
> > rule "testing maps"
> >   dialect "mvel"
> >   when
> >   $str: String()
> >   // $m: Map( this[$str] == 1 ) # error
> >   // $m: Map( this.$str == 1 )   # error
> >   // $m: Map( this["$str"] == 1 ) # compiles but rule won't
> fire
> >   $m: Map( this["a"] == 1 ) # this works however!
> >   then
> >   System.out.println($m[$str]); #also works with String and
> Map objects & no
> > conditions
> > end
> >
> > It obviously doesn't like it when I try to use the String object as the
> key
> > for the map. But it works when I use a String literal as the key. What am
> I
> > doing wrong?
> >
> > Does anyone have any suggestions please, or shall I give up and either
> use
> > eval as mentioned in
> > http://www.mail-archive.com/rules-users@lists.jboss.org/msg09716.html or
> use
> > the map as a field of another object which I insert instead of the map
> (in
> > fact that was my original plan!)?
>
> In exactly this thread Marc answered to that problem.
> http://www.mail-archive.com/rules-users@lists.jboss.org/msg09837.html
>
> His first idea is that this is a bug in the mvel dialect.
> I tried exactly that. I had a global var and put the string "a" into it.
> Then I wanted to check if Map( this[myVar] == 1 ) but this didn't work.
>
>
> > I'd also need to test for null i.e. whether a key/value pair exists for a
> > given String as the key.
>
> This seems to be only true when you go the route that I go, namely using
> the default rule syntax, i.e., eval.
>
>
> 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
>



-- 
 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] Maps in Drools

2009-08-18 Thread André Thieme
KDR schrieb:
> Hi, I'm relatively new to both Java and Drools. I'm trying to figure out how
> to use maps in Drools. I've looked at the thread
> http://www.mail-archive.com/rules-users@lists.jboss.org/msg09802.html
> 
>>From what I've read generally it seems best to insert objects directly
> rather than use nested accessors. So I've been experimenting with trying to
> insert a map and then checking stuff in it.
> 
> I set up a simple test map of String to Integer, with just "a" as key and 1
> as value, and "b" with 2.
> Map map = new HashMap();
> map.put("a", 1);
> map.put("b", 2);
> String a = "a";
>   
> I then inserted the map and also inserted the String a of value "a".
> 
> Here's the test rule, with various things I tried commented out:
> 
> rule "testing maps"
>   dialect "mvel"
>   when
>   $str: String()
>   // $m: Map( this[$str] == 1 ) # error
>   // $m: Map( this.$str == 1 )   # error
>   // $m: Map( this["$str"] == 1 ) # compiles but rule won't fire
>   $m: Map( this["a"] == 1 ) # this works however!
>   then
>   System.out.println($m[$str]); #also works with String and Map 
> objects & no
> conditions
> end
> 
> It obviously doesn't like it when I try to use the String object as the key
> for the map. But it works when I use a String literal as the key. What am I
> doing wrong?
> 
> Does anyone have any suggestions please, or shall I give up and either use
> eval as mentioned in
> http://www.mail-archive.com/rules-users@lists.jboss.org/msg09716.html or use
> the map as a field of another object which I insert instead of the map (in
> fact that was my original plan!)?

In exactly this thread Marc answered to that problem.
http://www.mail-archive.com/rules-users@lists.jboss.org/msg09837.html

His first idea is that this is a bug in the mvel dialect.
I tried exactly that. I had a global var and put the string "a" into it.
Then I wanted to check if Map( this[myVar] == 1 ) but this didn't work.


> I'd also need to test for null i.e. whether a key/value pair exists for a
> given String as the key.

This seems to be only true when you go the route that I go, namely using
the default rule syntax, i.e., eval.


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