OK - here is a first cut at an explanation of "parametric, polymorphic
rules"

Please find attached a text file

Thank You

----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, August 26, 2003 1:19 PM
Subject: Re: JESS: Re: Subrules


> I think Rich Halsey wrote:
>
> > This already exists in JESS whether you match on classes or
> > interfaces, it's just that many people do not even consider using it
> > because it is somewhat abstract (it is definitely NOT "see spot
> > run").
>
> Hmmmm. Can you give us an example of what you're talking about --
> sounds interesting!
>
>
>
> ---------------------------------------------------------
> Ernest Friedman-Hill
> Distributed Systems 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]
> --------------------------------------------------------------------
>
Polymorphic Rules
-----------------

Assume we have some base class such as:

class Animal {
        protected boolean hungry = false;
        protected String name = null;
        protected String sound = null;
        protected String food = null;

        public Animal(String _name, boolean _hungry, String _sound, String _food) { 
                name = _name;
                hungry = _hungry;
                sound = _sound;
                food = _food;
                }
        public boolean isHungry() { 
                return( hungry ); 
                }
        public void speak() {
                System.out.println("I am a " + name + " and I say " + sound}
        }
        public void eats() {
                System.out.println("I eat " + food}
        }
        }
} // end class

and some derived classes with the method speak overridden:

class Dog extends Animal {
        public Dog(String _name, boolean _hungry, String _sound, String _food) { 
                super(_name, _hungry, _sound, _food)            
                }
} // end class

class Cat extends Animal {
        public Cat(String _name, boolean _hungry, String _sound, String _food) { 
                super(_name, _hungry, _sound, _food)            
                }
} // end class

class Bird extends Animal {
        public Bird(String _name, boolean _hungry, String _sound, String _food) { 
                super(_name, _hungry, _sound, _food)            
                }
} // end class

Then if we construct some rule (using pseudocode):

/////////////////////////////////////////////////////////////////////////////////////
Rule AnimalSound {
        if 
                thereExists Animal pet;
        then
                pet.speak();
        }
/////////////////////////////////////////////////////////////////////////////////////

And we assert instantiations of a Dog, Cat, and a Bird into the working memory as in:

RuleEngine.assert( new Dog("Dog", true, "WOOF") );
RuleEngine.assert( new Cat("Cat", true, "MEOW") );
RuleEngine.assert( new Bird("Bird", true, "CHOIP") );

and when we signal the engine to run, our rule system should produce as
output the following lines in some order:

I am a Dog and I say WOOF
I am a Cat and I say MEOW
I am a Bird and I say MEOW

As we can see, there is only a single rule defined and it matches objects by a base 
class
on the LHS. Where a match occurs the method "speak()" is invoked on the RHS. If we had 
defined
the base class Animal as an interface instead of a class and then implemented this 
interface
for the Dog, Cat, and Bird classes the rule would have worked exactly as before. 
Obviously,
using an interface instead of a base class for matching has its own design 
considerations
for the rules.

This rule "polymorphism" exists in JESS as a byproduct of Java and can be used to 
simplify
the implementation of a rule-based system. However, it does add a level of abstraction 
since
the rules are NOT explicitly searching for derived classes (interfaces) but match on 
the 
base class (interface). The abstraction gets deeper as you define deeper hierarchies of
classes (interfaces). As in "there is no free lunch", the tradeoff must be considered 
when
building the system - can the people who maintain the resulting rule system understand 
the
abstraction or will it overwhelm them ?

Parametric Rules
----------------

If we have a system that uses another rule to match Dog, Cat, or Bird objects to Food
objects and we define a Food class hierarchy as:

class Food {
        public Food() {}
} // end class


class Bone extends Food {
        public Bone() {
                super();
                }
} // end class

class Seed extends Food {
        public Seed() {
                super();
                }
} // end class

class Tuna extends Food {
        public Tuna() {
                super();
                }
} // end class

Of course, our pets have a menu to choose from which is based on a decision table 
meaning
that they will eat only when certain conditions have been met in the decision table, 
as in:

boolean         petHungry                       T       F       T       F
boolean         compatibleFoodType      T       T       F       F

Knowing this, we prepare a class to hold the situations defined in the decision table.

class MenuDecision  {
        public boolean petHungry = false;
        public boolean compatibleFoodType = false;
        public Food foodType = null;
        public Animal petType = null;

        public MenuDecision(boolean _petHungry, boolean _compatibleFoodType, 
                        Food _foodType, Animal _petType) {
                petHungry = _petHungry;
                compatibleFoodType = _compatibleFoodType;
                foodType = _foodType;
                petType = _petType;
                }

        }
} // end class

Now we assert instantiations of a Dog, Cat, and a Bird into the working memory as in:

RuleEngine.assert( new Dog("Dog", true, "WOOF") );
RuleEngine.assert( new Cat("Cat", true, "MEOW") );
RuleEngine.assert( new Bird("Bird", true, "CHOIP") );

and then we instantiate some food objects:

RuleEngine.assert( new Bone() );
RuleEngine.assert( new Seed() );
RuleEngine.assert( new Tuna() );

and (finally) we instantiate some MenuDecision objects to represent the decision
table situations. Obviously, this may not represent the total picture of what we
are doing, but ... :

RuleEngine.assert( new MenuDecision(true, true, Bone, Dog) );
RuleEngine.assert( new MenuDecision(true, false, Bone, Cat) );
RuleEngine.assert( new MenuDecision(true, false, Tuna, Dog) );
RuleEngine.assert( new MenuDecision(false, false, Tuna, Dog) );


Since this is only for fun, I can claim that I have already defined a rule:

/////////////////////////////////////////////////////////////////////////////////////
Rule AnimalEats {
        if 
                thereExists Animal pet;
                thereExists Food petFood;
                thereExists MenuDecision menuDecision(
                        petType == pet;
                        foodType == petFood;
                        petHungry == pet.hungry;
                        compatibleFoodType == true;
                        ;
        then
                pet.eat();
        }
/////////////////////////////////////////////////////////////////////////////////////

Now, we have a one-rule system that analyzes all the possible situations from our 
decision table and where the rule matches according to our specification we will
get our results.

I have used 3 pets, 3 foods, and 4 situations which should make 36 possible 
combinations
to analyze by one rule. If one can imagine a larger system with, let's say 200 pet 
types,
300 types of food, and the same number of situations then one should see that by 
raising
the abstraction we can begin to get our arms (and whatever) around the problem. If we 
did 
not use this kind of abstraction and we also had other rules where forward chaining 
comes
into play then we might wish we had taken another career path.

Hopefully, I wrote all of this correctly - no, I did not try to compile it. If there 
are 
mistakes then maybe we can all try to fix it. I have used this technique very 
successfully
on different projects. This was NOT intended for the "guru" class but for the mere 
mortals
out here who struggle while trying to fathom the magic of rule based engineering.

If you got this far, thank you for your patience -

Rich Halsey

Reply via email to