Working Memory

Introduction

The working memory is where all knowledge is contained, each item of knowledge is called a Fact. The working memory is often referred to as the fact space; facts can be asserted, modified and retracted from the working memory using the methods:

Fact Manipulation

KnowledgeHelper

All fact manipulation during the execution of a consequence is done via the org.drools.spi.KnowledgeHelper class, an instance of this class is exposed to the consequence via the variable "drools":

public void assertObject(Object object) throws FactException;
public void modifyObject(Object object) throws FactException;
public void modifyObject(Object oldObject, Object newObject) throws FactException;
public void retractObject(Object object) throws FactException;

During the consequence you don't need to deal with fact handles as the KnowledgeHelper, "drools", does an object->handle lookup based upon identity of the object passed in. This can cause a problem if the identity of the object changes, such as when you try to update an immutable object like Integer, String etc. If the identity of the object changes then there is no handle associated with the new object.

There are two solutions for this; mutable object wrappers or the two arg version of modifyObject.

Two arg modifyObject:

modifyObject(Object oldObject, Object newObject);

MutableWrapper example:

public class MutableInteger {
    private int integer;
    public MutableInteger(int integer) { set(integer); }
    public void set(int integer) { this.integer = integer; }
    public int get() { return this.integer; }
    public String toString() { return String.valueOf(this.integer); }
    // you'll also need to write an equals() method for a complete working solution
}

assertObject

Objects are asserted into the WorkingMemory, which allows the rule-engine to be aware of its existence, and a fact handle is returned as a reference. Once asserted, the fact may be used to satisfy some portion of any rule's activation condition.

WorkingMemory memory = ruleBase.newWorkingMemory();

FactHandle handle1 = memory.assertObject( factOne );
FactHandle handle2 = memory.assertObject( factTwo );
FactHandle handle3 = memory.assertObject( factThree );

When an object is asserted the rete algorithm updates its graphs as new conditions become true.

Facts can also be asserted while rules are firing by using the assertObject method in the rule consequence:

<java:consequence>
    drools.assertObject( objectOne );
    drools.assertObject( objectTwo );
    drools.assertObject( objectThree );
</java:consequence>
_*Note: Prior to the beta-16 release, the syntax was simply "assertObject(...)" instead of "drools.assertObject(...)"._

Asserting a fact during consequence execution can cause other rules to match and fire once the current consequence has finished executing.

modifyObject

Facts already asserted into the working memory can be modified using the FactHandle obtained from a previous invocation of assertObject(...); modifyFact(...) allows the engine to know a meaningful change has been made.

Over time, knowledge may change. Instead of always retracting old facts and asserting new ones, it is sometimes advisable to view a change in knowledge as the modification of a single fact. For example, the fact about the current state of the weather may change as the weather changes. Instead of retracting a 'rainy' fact and asserting a 'sunny' fact, it is possible to simply change the value of the general 'weather' fact:

WorkingMemory memory = ruleBase.newWorkingMemory();

FactHandle weatherHandle = memory.assertObject( new Weather( "rainy" ) );

memory.modifyObject( weatherHandle,
new Weather( "sunny" ) );

The most important reason to perform fact modification instead of an assertion and a retraction is that rules with truth durations will automatically deactivate if a matching fact is retracted. If a fact is modified but still matches a rule with a truth duration, the clock on the duration timer is not reset.

Facts can also be modified while rules are firing by using the modifyObject method in the rule consequence:

<java:consequence>
    object.setWeather("sunny");
    drools.modifyObject( object );
</java:consequence>
_*Note: Prior to the beta-16 release, the syntax was simply "modifyObject(...)" instead of "drools.modifyObject(...)"._

Modifying a fact during consequence execution can cause other rules to match and fire once the current consequence has finished executing. It can also alter the agenda causing facts originally scheduled to fire to no longer fire.

retractObject

Objects already asserted into the working memory can be retracted using the FactHandle obtained from a previous invocation of assertObject(...); retractObject(...) removes objects from consideration by the engine. Once retracted, the fact can not be used to satisfy any portion of any rule's activation condition.

WorkingMemory memory = ruleBase.newWorkingMemory();

FactHandle handle = memory.assertObject( factOne );

memory.retractObject( handle );

When an object is retracted the rete algorithm updates its graphs as previously true conditions become false.

Facts can also be retracted while rules are firing by using the retractObject method in the rule consequence:

<java:consequence>
    drools.retractObject( object );
</java:consequence>
_*Note: Prior to the beta-16 release, the syntax was simply "retractObject(...)" instead of "drools.retractObject(...)"._

Retracting a fact during consequence execution can alter the agenda causing facts originally scheduled to fire to no longer fire.

Rule Firing

fireAllRules

As knowledge is manipulated within a WorkingMemory, no rules are actually
triggered to be fired. Instead, rules are activated, which makes them candidates
for being fired. Rule activations are placed upon the Agenda.

WorkingMemory memory = ruleBase.newWorkingMemory();

FactHandle weatherHandle = memory.assertObject( new Weather( "rainy" ) );

memory.fireAllRules();

When an application determines that the current state of knowledge is consistent and should be acted upon, the application may cause the activations on the agenda to begin firing. The fireAllRules(...) method blocks until the agenda has been completely cleared of activations.

Note that as an activation fires, its consequence may perform knowledge manipulation by asserting new facts, retracting existing facts, or modifying existing facts. All of these activities may cause activations to be added to or removed from the agenda.

Modifying facts can cause the currently executing rule to fire again causing infinite recursion; the rule attribute no-loop, which can be set to "true" or "false", allows you to control this behaviour.

Labels

 
(None)