Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Seeking configuration language for rules based system.

by ehdonhon (Curate)
on May 15, 2002 at 02:19 UTC ( #166635=perlquestion: print w/replies, xml ) Need Help??

ehdonhon has asked for the wisdom of the Perl Monks concerning the following question:


I have a rather complex shopping cart system which needs to be able to figure out a lot of things about the prices of the items in a user's cart. I need the system to updatable by somebody that knows less about the system than me. I think that the best way to do this is if I could provide a configuation system that encodes a series of rules about the system in a document that is seperate from the actual program. Here are some examples of the kinds of things I want to encode:

  • Widgets cost $250
  • Gizmos cost $125
  • All customers that have had at least three orders from us in the past get a 20% discount.
  • Buy 3 Widgets and we'll throw in a Gizmo for free.
  • Certain classes of customers get 50% off. (This is applied before the 20% discount)
  • Buy at least 10 Gizmos, and we'll reduce the cost by $30 per unit (This applies after the 50% discount if they get it, but before the 20% discount if they get that).
  • If you buy the service agreement that goes along with the Widgets during this month, we'll sell you the first year of the agreement for free when you sign up for at least a three year agreement.

This seems to me like it could become very confusing, and very ad-hoc in a short period of time. I really hate to re-invent the wheel on this sort of thing (especially when it is a very large wheel). I was wondering if there were any formats that people have already come up with for defining rules in systems like these? I looked through CPAN, but nothing really jumped out at me.

Thanks in advance for any pointers.

  • Comment on Seeking configuration language for rules based system.

Replies are listed 'Best First'.
Re: Seeking configuration language for rules based system.
by mattr (Curate) on May 15, 2002 at 10:34 UTC
    It would be nice to have a real configuration language, perhaps which uses opencyc which (when done) should be able to do the hard part. But not needed I think for your immediate problem. Incidentally I did not know about JESS, but did know about the CLIPS expert system package which it grew out of, and CLIPS is public domain. I have not used CLIPS but it does have a rule-based mode. There are example CLIPS programs here and while it would be very cool to use CLIPS in Perl, I think this sounds like overkill for your project.

    I once had a problem where I thought of using rules and ended up encapsulating page layout subroutines so that I could write custom layout rules in a line or two of perl each. The motivation was that we had no database or perl, but we had a lot of content with similar layout for each hotel, plus not enough time to do it all by hand, and knowledge that changes might even so come in late (they did). This let me build a thousand page static website for fourteen hotels in the Mandarin Oriental group. Along with image compositing code I built with the gimp's perl server it resized all the photos and generated the entire site in just a few minutes. I call it "Magic Hands" because it looks like a really fast designer is sitting in front of Gimp and doing all the photo work.

    In this case I had a lot of control since the "rules" were Perl code, and I was able to rebuild the entire site with new content a few times with extremely little pain, which is where it paid off. For example I could modify one entry in a data structure which said that for example we had two more photos for the Singapore franchise, and it would reinvent all the photo thumbnails, page navigation, and so on.

    The neat thing is that once you find it is really easy to add something new, you do and you gain things you didn't think were possible. For example in my project you click on thumbnails to view images of hotel interiors, but we had given up on the idea of highlighting the clicked thumbnail. I was able to add this and even arrange the photos in a circle no matter how many photos there were on each page. Also, since I was able to refer to the parsed template files in the program, I was able to change where a certain link would go for every hotel just by changing a line of perl. I think you may find similarly that it becomes easy to add campaigns.

    In your case a straightforward html form could make an easy-to-use interface which depending on your implementation might sacrifice power for ease of use. There was a recommendation above about looking at Outlook. Having helped someone recently clear his Eudora files of spam, I'd take a look at Eudora's mail filtering interface. Their downloadable manual shows how they let you actually do a lot of really great things, even regexes. You can also see an online tutorial and download Eudora itself. Their use of different ways to get to the same screen was confusing for me, but look at their documentation.. you will need to write a manual.

    As an aside, one company I knew some years ago, Intertrust, actually was working on e-commerce rules (and I think Softbank is a partner) but it looks like they've refocused on digital rights management. I just mention them because I think they might have some patents regarding specification of chains of resellers but I think that is not something you need to worry about.

    Anyway, look at Eudora's filters screen and see how it might apply to your interface. I'd recommend first rewriting your wishlist in pseudocode as if-then statements. This will help you see datasets which you will want to let your users maintain through separate form interfaces. For example a list of preferred customer classes might be one. Certainly the list of normal product prices is another set of data that should be handled with a separate interface. Then this rule-based form is for is for special cases and business logic only.

    You'll need to make up a list of supported functions and handle internally logic (not done in Eudora) to make sure for example that even if you accumulate discounts you don't go beyond a certain percentage. (I recently saw a shopping cart that let you earn money.) This analysis will be needed even if you used someone else's system.

    Another kind of interface which I find somewhat appealing would be to require the user to type rules in Perl code into an HTML text input field, and eval them in order. This would have the advantage of allowing you or another Perl person to do complicated things while they can do simple things without much help, possibly just changing a couple of numbers. You could put your error-checking logic into similar statements as well and even modify them from the web. One things you might consider is letting them type english words like "greater than" instead of the mathematical operators. You might even find some use in using a readline/prompt based shell that would eval commands you type in against test data to try out new rules.

    Looking at it this way, your business logic starts to look like this..

    DiscountAll(0.5) if CustomerClass = Student AdjustPrice(Gizmo, 30.00) if Quantity(Gizmo) > 9 DiscountAll(0.2) if OrdersToDate > 2 OfferFreeProduct(Gizmo) if Quantity(Widget) > 2 AdjustPrice(WidgetPlanB, 250.00) if Quantity(WidgetPlanB) > 2
    Obviously you could make everything much more complex. This example is going to need only three data queries and three functions to change the order form.

    Also it might be a good idea to let them type "if" first and let them type "then" instead of a curly-bracketed block. Likewise just an equals sign instead of "eq" perhaps. Maybe you could add the keyword "matches" which would let them type an alphanumeric string that could be used to match product or customer class names. You could even teach your customer a little SQL though maybe that's where angels fear to tread.. :) This could be useful for lots of things, please share your successes.

Re: Seeking configuration language for rules based system.
by lachoy (Parson) on May 15, 2002 at 03:23 UTC

    For inspiration, if not for direct usage, you might take a look at Jess. It's in Java, but the source is available. In particular, the language it uses has been tested and modified over time and may provide some ideas. Jess, like many other rules engines, implements the Rete algorithm, which seems to be the standard. There's also a (relatively) open process to make a standard API/library in Java for this.

    M-x auto-bs-mode

      I had a look at this package and was fairly impressed with it up until I reviewed the licencing for the package, which may present some hurdles to those looking at incorporating Jess by itself into their own development. In summary from the download page ...

      • Jess software, owned by Sandia National Laboratories, will be made available upon request at no cost to U.S. Federal Government Agencies for their own internal use. Sandia will also provide Jess to Universities, Academic Institutions, and other U.S. National Laboratories, for their own internal research and development, through a no cost, restricted R&D license. Any internal or commercial use of Jess requires a commercial license that can be negotiated as a running royalty or a fully paid up-front fee.
      • Our commercial license will grant your company, the LICENSEE, a nontransferable, nonexclusive right to use Jess Software to create derivative works by embedding Jess into your product(s) and to copy and distribute Jess software as embedded into your Product(s).
      • Note: Jess is not licensed under the GPL, the LPGL, the BSD license, or any other free software or open source license. Redistribution of the Jess source code under any free software or open source license is prohibited under this agreement.


Re: Seeking configuration language for rules based system.
by samtregar (Abbot) on May 15, 2002 at 03:01 UTC
    How much time do you want to spend on the project? I bet you could build something pretty nice given a few weeks of work. Will it be worth it? Think carefully before answering. I have a hunch you've drawn yourself up a nice technical challenge that probably isn't justified by the required functionality.

    Of course, it does sound like a lot of fun! I think I'd model a solution based on filter configuration systems ala Outlook. Basically a GUI that allows you to configure a series of rules that are then evaluated for each record. You'd have to pre-define a series of available functions and fields, but otherwise it could be very flexible.


Re: Seeking configuration language for rules based system.
by Biker (Priest) on May 15, 2002 at 07:45 UTC

    From your description it sounds like this is a commercial system where one could assume a certain level of commitment and some serious resource availability. (Correct me if/where I'm wrong.)

    I here assume that you have a backend database for prices, 'gizmos', etc. I guess it's some kind of SQL database. If so, I would implement the rules system in the backend database.

    You build your frontend application to understand possible generic rules like 'volume discount percentage' and 'volume discount threshold'.

    Then you let your co-worker manipulate the rules in the database, using any tool s/he's comfortable with. Either a specific tool built by you or a generic database manipulation tool, all depending on your co-workers skills.

    So your co-worker could make sure that for 'gizmo', the client must by 30 units before having a volume discount, but for 'thing' the client must buy 50 units. Furthermore, the volume discount for 'gizmo' is 20% whereas for 'thing' it's 23%. Etc.

    Everything went worng, just as foreseen.

Re: Seeking configuration language for rules based system.
by perrin (Chancellor) on May 15, 2002 at 16:12 UTC
    Don't do it. I am currently working with a Java system called ATG Dynamo. It has a very complete rules-based system for promotions and discounts. It sucks.

    Why does it suck? Because accounting for all possible kinds of discounts means you end up building a complex configuration language and a pretty heavy engine for interpreting it. It's way too complex for a non-tech person to comfortably work with, and thus it fails at its goal.

    I suggest you write an interface for plugging in short pieces of code (maybe use the Strategy design pattern), and write these rules yourself in clean, well-commented perl. They will be much more efficient, and probably require less time to change if you have a competent perl programmer and a reasonable API.

      Yeah, I agree. I've also used CLIPS on several projects. Also Prolog. These aren't easy systems for a non-programmer to use directly.

      You can make CLIPS (or, IMO any rule-based system) easy to use like this in one dimension, but not the dimension you want. For example, I had a system for diagnosis according to DSM-IV criteria. It had a nice interface for users to enter new "facts", which the rules would then run against. But, allowing users to be able to add new rules (and preserve the existing dependencies and logic) would have been way more difficult (or impossible).

      How about the "standard" way of solving this? From your description of the problem, it's exactly what OO programming is about. You create business objects in clean OO code, and give them methods that model the business rules. The methods only allow the various operations to go through if whatever criteria is met. This is a really clean way to code, and yeah - you need an OO programmer to maintain it. But, the problem itself requires it, I think.

      I definitely agree with Perrin. The most effective, usable system is going to be a framework that allows you to glue together concise, targeted bits of code. You can't beat the power of Perl for scripting complicated interactions between little bits of data.

      We use XML::Comma for managing web-site user profiles, mailing list systems, content archives, etc. We haven't done quite this kind of shopping cart, but it's a pretty good fit.

      In Comma, you write document definitions that specify data structures, constrain the contents of the parts of those structures, and govern how data is saved in filesystem- and database-backed storage. There's a pretty extensive API for manipulating both individial documents and collections of docs.

      You always hand-write the definitions -- that's the core exercise of figuring out basic data structures and behaviors. Writing defs feels like a kind of OO mating ritual: XML on one side, perl on the other, and between the two of them a Class is born.

      Most of our systems are built to assume completely tools-generated docs (for various definitions of "tools"). You can write docs by hand, and for your shopping cart system you might want to. For instance, creating a new "item" in the product catalog could be the job for a decent programmer who understands something about how the system is used but doesn't have much knowledge of the internals/architecture/subtleties.

      Anyway, I threw together a bit of Comma stuff showing how you might structure your widgets & gizmos example. Whether or not you want to look more at Comma, it might provide some more food for thought. There are a few example "item" and "customer" docs, followed by defs for "item", "customer" and "cart".

      <item> <name>widget</name> <base_cost>250</base_cost> </product> <item> <name>gizmo</name> <base_cost>125</base_cost> <cost_hook> <apply_order>100</apply_order> <!-- buy three widgets, get a gizmo free --> <cod><![CDATA[ sub { my ( $cart, $item, $customer, $cost ) = @_; if ( scalar(@{$cart->elements('widget')}) > 2 ) { return 0; } else { die; } ]]></cod> </cost_hook> <!-- buy 10 widgets, get $30-off per --> <cost_hook> <apply_order>110</apply_order> <cod><![CDATA[ sub { my ( $cart, $item, $customer, $cost ) = @_; if ( $cart->number_of('gizmo') > 10 ) { return $cost - 30; } else { die; } } ]]></cod> </cost_hook> </item>
Re: Seeking configuration language for rules based system.
by mr_mischief (Monsignor) on May 15, 2002 at 16:27 UTC
    Personally, I'd make the configuration language Perl code that can be evaluated. I'd have this generated programmatically from an interface the user can understand. I'd store the code in the database along with the product. I'd also store enough of the rules that went into creating the Perl code in the database that the UI could show the original rules for perusal. Finally, I'd have a field specifically to tell in what order the rules ar eto be applied.

    I have a specific idea of how I'd do the rules entry interface if you're interested...

    From the rules listed in the my UI description, it's easy to generate code in the style of simple if statements. The specific ordering lets you do each one independent of the others, in the order specified by the user. The only thing this doesn't take into account in the simple manner of its design is to make the rules interact based on the results from the other rules. Even that should be possible with extra variables to be set and checked, but that's beyond the scope of this node and is left as an exercise for now.

    Christopher E. Stith
    Do not try to debug the program, for that is impossible. Instead, try only to realize the truth. There is no bug. Then you will find that it is not the program that bends, but only the list of features.
Re: Seeking configuration language for rules based system.
by bserfaty (Novice) on May 15, 2002 at 16:32 UTC
      Now, I love Guile (see Inline::Guile for proof) but why would you suggest it for this project? Guile is a Scheme interpreter. Scheme supports functional programming ala Lisp. It has nothing to do with rule-based systems.


        Well, I said I'm not sure that guile is what he needs.
        I suggested it because, believe it or not, we (the development team I'm working at) are currently looking into guile as a base for implementing a rule based system.
        Rule based system can be (beautifully) implemented through Scheme. In the book Structure and Interpretation of Computer Programs there is a nice implementation of a rule based system in Scheme <A HREF=">here.
        Thanks a lot for pointing me to the module. I will defently look into that.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://166635]
Approved by VSarkiss
Front-paged by impossiblerobot
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2020-10-25 16:49 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (249 votes). Check out past polls.