Exactly.

I have an initial set of rules in several .clp text files and load those
as batches when the system starts up. Included within those rules are
two meta-rules that function as I described in my post, to add more
rules as needed at runtime using the build function.

Since my original post, I discovered that adding rules at runtime as I
had been doing resulted in ever-increasing times to call build. I think
this is because while a given "set" of generated rules will only match a
certain subset of facts, when new rules are added an attempt is made to
match all facts against them.

In any event, I now pre-generate a reasonable number of these rules at
system initialization time. To do this I write tmp facts to a file and
batch load them, and use the same backchaining mechanism to trigger the
meta-rules by matching on these tmp facts. I did this in order to keep
the backchaining as previously described to add rules if the users go
beyond what we expect them to do.

dave


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On Behalf Of [EMAIL PROTECTED]
Sent: Friday, March 10, 2006 3:27 PM
To: [email protected]
Subject: Re: JESS: Dr. StrangeJess

Look carefully at his message -- he built up the rules as Strings in
Jess code and used "build" to compile them.


I think Roger Studner wrote:
[Charset iso-8859-1 unsupported, filtering to ASCII...]
> Question.. how are you loading the generated rules into the jess
engine?
> 
> do you create files on the filesystem and then batch them in?
> 
> I can obviously create rules a ton of ways.. but didn't know if you 
> did it via DefRule API.. or if you build text files and then used 
> 'batch' to load them in?
> 
> Any help would be great,
> Roger
> 
> 
> On 3/9/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]>
wrote:
> >
> > How I learned to stop worrying and love the meta-rule.
> >
> > Long post warning, if you're not interested in my possibly rambling 
> > nature. I do have a couple questions regarding common patterns in 
> > Jess at the end, which I would appreciate a little feedback on if 
> > you have a few minutes.
> >
> > Regarding my recent post about performance, I was able to resolve it

> > this morning solely by making changes to the rules. How? By making 
> > more rules and have them rely on constants where possible instead of

> > variables.
> >
> > Like probably many people, I came to Jess & rules systems after many

> > years (15 - egad!) of object-oriented programming over relational 
> > databases. That way of thinking for so long can sure program the 
> > mind to work a certain way, and it can take some time to deprogram. 
> > Anyway, in the slow version of my system, I had 3 core rules causing

> > bottlenecks and they took this general form (a simplification, and 
> > they also seek min/max values of some values, but it gets the idea
across):
> >
> > (defrule do-it
> > (aaa (a ?a) (b ?b) (c ?c) (d ?d) (e ?e) (f ?f)) (bbb (a ?a) (b ?b) 
> > (c ?c) (d ?d) (g ?g) (h ?h) (i ?i)) (ccc (a ?a) (b ?b) (c ?c) (d ?d)

> > (j ?j)) => ;do something meaningful
> > )
> >
> > The thing about this, is that the values for ?a ?b ?c ?d are taken 
> > from lookup tables in a database, and vary for each request into the

> > system depending on user actions in a client application (each 
> > service request asserts a few facts, causing rules to fire which 
> > possibly update some shadow-facts, and then collects the updated 
> > state from the underlying java beans to return to the user). There 
> > are only a few possible values for each of these variables, but 
> > combined with the facts that contain them, I was getting an enormous

> > number of partial matches. And I do mean a lot. Profiling showed 
> > that with only about 5000 facts in the system, a single service 
> > request was causing 10+ million value comparisons to be made. Ouch.
> >
> > I've had this problem in the back of my mind for several weeks, and 
> > investigated some other avenues such as the profiling I mentioned, 
> > without really getting anywhere. This morning I finally saw the
light:
> > "static queries on dynamic data" - of course! The lookup values are 
> > really static data, and shouldn't be treated like query parameters. 
> > What I had been doing was using these variables to qualify the LHS 
> > much the same way a sql query would work. But, that goes against 
> > "sql: dynamic queries on static data, jess: static queries on
dynamic data".
> >
> > Then I started thinking about turning those variables into constants

> > and having a separate rule for every permutation and if that would 
> > reduce all those partial matches and millions of comparisons. Would 
> > it be hard to write a meta-rule to write these rules? Turns out it 
> > was ridiculously easy.
> >
> > I already had some backchaining going on, that was fetching in some 
> > other db data the first time a given combination of ?a ?b ?c ?d was 
> > encountered (to assert aaa & bbb facts, among a few other things). I

> > added another backchained fact to keep track of which permutations 
> > had yet to have their rules written, and ended up with something
like this:
> >
> > (defrule get-do-it-rules
> > (need-do-it-rules (id ?) (a ?a) (b ?b) (c ?c) (d ?d)) => (bind ?cmd 
> > (str-cat
> >   " (defrule do-it-" ?a "-" ?b "-" ?c "-" ?d
> >   "  (aaa (a "?a") (b "?b") (c "?c") (d "?d") (e ?e) (f ?f))"
> >   "  (bbb (a "?a") (b "?b") (c "?c") (d "?d") (g ?g) (h ?h) (i ?i))"
> >   "  (ccc (a "?a") (b "?b") (c "?c") (d "?d") (j ?j) )"
> >   " =>"
> >   "  ;do something meaningful"
> >   " )"))
> > (build ?cmd)
> > (assert (do-it-rules (id gensym*) (a ?a) (b ?b) (c ?c) (d ?d)) )
> >
> > resulting in rules that look like:
> >
> > (defrule do-it-400-600-1-300
> > (aaa (a 400) (b 600) (c 1) (d 300) (e ?e) (f ?f)) (bbb (a 400) (b 
> > 600) (c 1) (d 300) (g ?g) (h ?h) (i ?i)) (ccc (a 400) (b 600) (c 1) 
> > (d 300) (j ?j) ) =>
> >   ;do something meaningful
> > )
> >
> > What happened was a big wow - I went from 3 core rules to over 200, 
> > and a run of the system went from 20+ seconds to < 1 second. This is

> > a huge win, considering this is a service that gets hit by our 
> > client application while the people that use it are on the phone 
> > with customers.
> >
> > While I could have done this outside of jess by writing java code to

> > generate a batch file containing the rule permutations, it was more 
> > natural in this case to just do it within jess. Overall though, is 
> > having many rules like this a common pattern? Is there a better 
> > route to go that would accomplish the same thing without generating 
> > hundreds of rules? Just wondering if I'm on the right track here or 
> > way out in left field.
> >
> > thanks a bunch,
> >
> > dave
> >
> >
> > --------------------------------------------------------------------
> > To unsubscribe, send the words 'unsubscribe jess-users
[EMAIL PROTECTED]'
> > in the BODY of a message to [EMAIL PROTECTED], NOT to the list 
> > (use your own address!) List problems? Notify 
> > [EMAIL PROTECTED]



---------------------------------------------------------
Ernest Friedman-Hill  
Advanced Software Research          Phone: (925) 294-2154
Sandia National Labs                FAX:   (925) 294-2234
PO Box 969, MS 9012                 [EMAIL PROTECTED]
Livermore, CA 94550         http://herzberg.ca.sandia.gov

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list (use
your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------


--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to