The Artima Developer Community
Sponsored Link

Java Buzz Forum
Types and Semantics in Drools

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Geoffrey Wiseman

Posts: 51
Nickname: diathesis
Registered: Aug, 2003

Geoffrey Wiseman is a software professional.
Types and Semantics in Drools Posted: Jan 18, 2005 8:58 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Geoffrey Wiseman.
Original Post: Types and Semantics in Drools
Feed Title: Furious Purpose
Feed URL: http://www.jroller.com/diathesis/feed/entries/rss
Feed Description: Thoughts and experiences on technology and software.
Latest Java Buzz Posts
Latest Java Buzz Posts by Geoffrey Wiseman
Latest Posts From Furious Purpose

Advertisement

As you compose complicated rule sets, you may find that you need to assert simple facts, normally handled by Java primitives, with different meanings. Because drools uses the type of the fact to determine which rules to examine, these primitives may overlap in confusing ways.

For instance, imagine that you're processing a pet food shopping cart using drools and, in so doing, want the option of supplying a discretionary discounts, based on the customer's shopping history and your own excess inventory. You decide to capture these as Float objects, one for the customer's relationship discretionary discount and another for the inventory discretionary discount.

If you simply assert both of these facts into memory, drools will be unable to determine which is which -- they're both Float objects with no additional semantics associated with them. That leaves several available options:

  • Send the float objects in as application data.
  • Subclass float to add semantic meaning by the names of the new classes.
  • Use the semaphore mechanism.

Application Data
The application data mechanism is a useful way to parameterize rules, but application data is not treated as a fact assertion, and will not activate rules. This makes it applicable in some, but not all rule design scenarios.

e.g.:

  ruleBase.newWorkingMemory();
  // ... assert facts here
  memory.setApplicationData( "relationshipDiscretionaryDiscount", new Float( 0.1f ) );
  memory.setApplicationData( "inventoryDiscretionaryDiscount", new Float( 0.05f ) );
  memory.fireAllRules();
  <application-data identifier="relationshipDiscretionaryDiscount">java.lang.Float</application-data>
  <rule name="Apply Discount">
    <parameter identifier="shopper">
      <class>commerce.Shopper</class>
    </parameter>
    <parameter identifier="item">
      <class>commerce.CartItem</class>
    </parameter>
    <java:condition>shopper.isLongTermCustomer()</java:condition>
    <java:consequence>
      item.applyDiscount( relationshipDiscretionaryDiscount );
      drools.modifyObject( item );
    </java:consequence>
  </rule>

Subclassing
By subclassing the float, you can create a class that has domain-specific semantic meaning and which can be used directly in your rules. For this example, you might create a generalized Discount class which can represent both kinds of discount as well as a type.

If this class has meaning in your domain, and by using it, you will make your application design more intention-revealing, and possibly add further functionality to the class, then this may well be the best way to go. However, if you're going to create a meaningless wrapper class, or several of them, this can be tiresome.

e.g.:

    ruleBase.newWorkingMemory();
    // ... assert facts here
    memory.assertObject( new RelationshipDiscretionaryDiscount( 0.1f ) );
    memory.assertObject( new InventoryDiscretionaryDiscount( 0.05f ) );
    memory.fireAllRules();
  <rule name="Apply Discount">
    <parameter identifier="item">
      <class>commerce.CartItem</class>
    </parameter>
    <parameter identifier="discount">
      <class>commerce.Discount</class>
    </parameter>
    <java:condition>item.getDiscount() < discount</java:condition>
    <java:consequence>
      item.applyDiscount( discount );
      drools.modifyObject( item );
    </java:consequence>
  </rule>

Alternately, you might directly subclass Float into both RelationshipDiscretionaryDiscount and InventoryDiscretionaryDiscount.

e.g.:

  ruleBase.newWorkingMemory();
  // ... assert facts here
  memory.assertObject( new Discount( Discount.RELATIONSHIP, 0.1f ) );
  memory.assertObject( new Discount( Discount.INVENTORY, 0.05f ) );
  memory.fireAllRules();
  <rule name="Apply Discount">
    <parameter identifier="shopper">
      <class>commerce.Shopper</class>
    </parameter>
    <parameter identifier="item">
      <class>commerce.CartItem</class>
    </parameter>
    <parameter identifier="discount">
      <class>commerce.RelationshipDiscretionaryDiscount</class>
    </parameter>
    <java:condition>shopper.isLongTermCustomer()</java:condition>
    <java:consequence>
      item.applyDiscount( discount );
      drools.modifyObject( item );
    </java:consequence>
  </rule>

Semaphores
As of Drools 2.0B19, Drools supplies semaphore classes that can be used for much of the same purpose. In essence, these are simple wrappers for Java primitives that are also named. This allows you to submit two facts with the same primitive type but with different names. The rules are aware of semaphores and can use these names to make distinctions between the supplied facts.

e.g.:

    ruleBase.newWorkingMemory();
    // ... assert facts here
    // This FloatSemaphore constructor doesn't yet exist: See DROOLS-280
    memory.assertObject( new FloatSemaphore( "relationshipDiscretionaryDiscount", 0.1f ) );
    memory.assertObject( new FloatSemaphore( "inventoryDiscretionaryDiscount", 0.05f ) );
    memory.fireAllRules();
  <rule name="Apply Discount">
    <parameter identifier="shopper">
      <class>commerce.Shopper</class>
    </parameter>
    <parameter identifier="item">
      <class>commerce.CartItem</class>
    </parameter>
    <parameter identifier="relationshipDiscretionaryDiscount">
      <semaphore type="Float" />
    </parameter>
    <java:condition>shopper.isLongTermCustomer()</java:condition>
    <java:consequence>
      item.applyDiscount( discount );
      drools.modifyObject( item );
    </java:consequence>
  </rule>

Read: Types and Semantics in Drools

Topic: Jazz Up Your JTables with Reusable Classes Previous Topic   Next Topic Topic: New Features in C# 2005

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use