![JAR search and dependency download from the Maven repository](/logo.png)
jadex.rules.rulesystem.rete.nodes.AlphaNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-rules Show documentation
Show all versions of jadex-rules Show documentation
Jadex Rules is a small lightweight rule engine, which currently
employs the well-known Rete algorithm for highly efficient rule
matching. Jadex rules is therefore similar to other rule engines
like JESS and Drools. Despite the similarities there are also
important differences between these systems:
* Jadex Rules is very small and
intended to be used as component
of other software. Even though rules can be specified in a Java
dialect as well as (a small variation of) the CLIPS language
its primary usage is on the API level. Jadex Rules is currently
the core component of the Jadex BDI reasoning engine.
* Jadex Rules cleanly separates between state and rule representation.
This allows the state implementation as well as the matcher to be
flexibly exchanged. Some experiments have e.g. been conducted with
a Jena representation. Regarding the matcher, it is planned to
support also the Treat algorithm, which has a lower memory footprint
than Rete.
* Jadex Rules pays close attention to rule debugging. The state as
well as the rete engine can be observed at runtime. The rule debugger
provides functionalities to execute a rule program stepwise and also
use rule breakpoints to stop the execution at those points.
package jadex.rules.rulesystem.rete.nodes;
import jadex.commons.SUtil;
import jadex.rules.rulesystem.AbstractAgenda;
import jadex.rules.rulesystem.rete.constraints.IConstraintEvaluator;
import jadex.rules.rulesystem.rete.extractors.AttributeSet;
import jadex.rules.state.IOAVState;
import jadex.rules.state.IProfiler;
import jadex.rules.state.OAVAttributeType;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* An alpha node is a 1-input -> 1-output node which
* propagates objects matching its constraints.
*/
public class AlphaNode extends AbstractNode implements IObjectConsumerNode, IObjectSourceNode
{
//-------- attributes --------
/** The object source. */
protected IObjectSourceNode osource;
/** The object consumers. */
protected IObjectConsumerNode[] oconsumers;
/** The constraint evaluator. */
protected IConstraintEvaluator[] evaluators;
/** The set of relevant attributes. */
protected AttributeSet relevants;
/** The set of indirect attributes. */
protected AttributeSet indirects;
//-------- constructors --------
/**
* Create a new node.
* @param evaluators The evaluators.
*/
public AlphaNode(int nodeid, IConstraintEvaluator[] evaluators)
{
super(nodeid);
this.evaluators = evaluators;
}
//-------- object consumer interface --------
/**
* Send a new object to this node.
* @param object The object.
*/
public void addObject(Object object, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
//System.out.println("Add object called: "+this+" "+object);
// if(object.getClass().toString().indexOf("Order")!=-1)
// System.out.println("here: "+object);
// if(state.getType(object).getName().indexOf("goal")!=-1)
// System.out.println("here: "+object);
state.getProfiler().start(IProfiler.TYPE_NODE, this);
state.getProfiler().start(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTADDED);
assert !mem.hasNodeMemory(this) || !((Collection)mem.getNodeMemory(this)).contains(object) : "New objects shouldn't be contained.";
if(checkConstraints(object, state))
{
((Collection)mem.getNodeMemory(this)).add(object);
//System.out.println("Object passed constraint check: "+this+" "+object);
propagateAdditionToObjectConsumers(object, state, mem, agenda);
}
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTADDED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
}
/**
* Send a removed object to this node.
* @param object The object.
*/
public void removeObject(Object object, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
//System.out.println("Remove object called: "+this+" "+object);
state.getProfiler().start(IProfiler.TYPE_NODE, this);
state.getProfiler().start(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTREMOVED);
if(mem.hasNodeMemory(this) && ((Collection)mem.getNodeMemory(this)).remove(object))
{
//System.out.println("Object passed constraint check: "+this+" "+object);
propagateRemovalToObjectConsumers(object, state, mem, agenda);
}
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTREMOVED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
}
/**
* Propagate an object change to this node.
* @param object The new object.
*/
public void modifyObject(Object object, OAVAttributeType type, Object oldvalue, Object newvalue,
IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
//System.out.println("Modify object called: "+this+" "+object);
state.getProfiler().start(IProfiler.TYPE_NODE, this);
state.getProfiler().start(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTMODIFIED);
if(getRelevantAttributes().contains(type))
{
// Check if modification changes node memory.
boolean affected = isAffected(type);
boolean contains = mem.hasNodeMemory(this) && ((Collection)mem.getNodeMemory(this)).contains(object);
if(affected)
{
boolean check = checkConstraints(object, state);
// Object no longer valid -> remove
if(contains && !check)
{
((Collection)mem.getNodeMemory(this)).remove(object);
propagateRemovalToObjectConsumers(object, state, mem, agenda);
}
// Object newly valid -> add
else if(!contains && check)
{
((Collection)mem.getNodeMemory(this)).add(object);
propagateAdditionToObjectConsumers(object, state, mem, agenda);
}
// Propagate modification for deeper nodes if here no change.
else if(contains)
{
propagateModificationToObjectConsumers(object, type, oldvalue, newvalue,
state, mem, agenda);
}
}
else
{
// Object changed in memory -> propagate modification
if(contains)
{
propagateModificationToObjectConsumers(object, type, oldvalue, newvalue,
state, mem, agenda);
}
}
}
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_OBJECTMODIFIED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
}
/**
* Propagate an indirect object change to this node.
* @param id The changed object.
*/
public void modifyIndirectObject(Object id, OAVAttributeType type, Object oldvalue, Object newvalue, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
Collection oldmem = getNodeMemory(mem);
Collection input = getObjectSource().getNodeMemory(mem);
if(input!=null)
{
// Todo: Use index for avoiding the need for checking all objects.
for(Iterator it=input.iterator(); it.hasNext(); )
{
Object object = it.next();
boolean contains = oldmem!=null && oldmem.contains(object);
boolean check = checkConstraints(object, state);
// Object no longer valid -> remove
if(contains && !check)
{
((Collection)mem.getNodeMemory(this)).remove(object);
propagateRemovalToObjectConsumers(object, state, mem, agenda);
}
// Object newly valid -> add
else if(!contains && check)
{
((Collection)mem.getNodeMemory(this)).add(object);
propagateAdditionToObjectConsumers(object, state, mem, agenda);
}
}
}
}
/**
* Set the object source of this node.
* @param node The object source node.
*/
public void setObjectSource(IObjectSourceNode node)
{
this.osource = node;
}
/**
* Get the object source of this node.
* @return The object source node.
*/
public IObjectSourceNode getObjectSource()
{
return osource;
}
//-------- object source interface --------
/**
* Add an object consumer node.
* @param node A new consumer node.
*/
public void addObjectConsumer(IObjectConsumerNode node)
{
if(oconsumers==null)
{
oconsumers = new IObjectConsumerNode[]{node};
}
else
{
IObjectConsumerNode[] tmp = new IObjectConsumerNode[oconsumers.length+1];
System.arraycopy(oconsumers, 0, tmp, 0, oconsumers.length);
tmp[oconsumers.length] = node;
oconsumers = tmp;
}
relevants = null; // Will be recalculated on next access;
}
/**
* Remove an object consumer.
* @param node The consumer node.
*/
public void removeObjectConsumer(IObjectConsumerNode node)
{
if(oconsumers!=null)
{
for(int i=0; i0)
System.arraycopy(oconsumers, 0, tmp, 0, i);
if(i© 2015 - 2025 Weber Informatics LLC | Privacy Policy