Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.rules.rulesystem.rete.nodes.CollectNode Maven / Gradle / Ivy
package jadex.rules.rulesystem.rete.nodes;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import jadex.rules.rulesystem.AbstractAgenda;
import jadex.rules.rulesystem.rete.Tuple;
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;
/**
* The purpose of a collect node is to compress a number of tuples to a
* new tuple, which contains a multi slot.
* Example: Incoming tuples are:
* [a, b, d1]
* [a, b, d2]
* [a, c, d3]
* [a, c, d1]
* ->
* [a, b, {d1, d2}]
* [a, c, {d3, d1}]
*/
public class CollectNode extends AbstractNode implements ITupleConsumerNode, ITupleSourceNode
{
//-------- attributes --------
/** The tuple consumers. */
protected ITupleConsumerNode[] tconsumers;
/** The tuple source. */
protected ITupleSourceNode tsource;
/** The constraint evaluator. */
protected IConstraintEvaluator[] evaluators;
/** The set of relevant attributes. */
protected volatile AttributeSet relevants;
/** The set of indirect attributes. */
protected volatile AttributeSet indirects;
/** The tuple index to collect. */
protected int tupleindex;
//-------- constructors --------
/**
* Create a new beta node.
*/
public CollectNode(int nodeid, int tupleindex, IConstraintEvaluator[] evaluators)
{
super(nodeid);
this.tupleindex = tupleindex;
this.evaluators = evaluators;
}
//-------- tuple source interface --------
/**
* Add an tuple consumer node.
* @param node A new consumer node.
*/
public void addTupleConsumer(ITupleConsumerNode node)
{
if(tconsumers==null)
{
tconsumers = new ITupleConsumerNode[]{node};
}
else
{
ITupleConsumerNode[] tmp = new ITupleConsumerNode[tconsumers.length+1];
System.arraycopy(tconsumers, 0, tmp, 0, tconsumers.length);
tmp[tconsumers.length] = node;
tconsumers = tmp;
}
relevants = null; // Will be recalculated on next access;
}
/**
* Remove an tuple consumer.
* @param node The consumer node.
*/
public void removeTupleConsumer(ITupleConsumerNode node)
{
if(tconsumers!=null)
{
for(int i=0; i0)
System.arraycopy(tconsumers, 0, tmp, 0, i);
if(i add
if(!nodemem.resultMemoryContains(resulttuple))
{
nodemem.addResultTuple(resulttuple);
propagateAdditionToTupleConsumers(resulttuple, state, mem, agenda);
}
// If constraints passed and in result -> modify
else
{
// todo:
propagateModificationToTupleConsumers(resulttuple, null, null, resulttuple, state, mem, agenda);
}
}
else
{
// If constraints not passed and in result -> remove
if(nodemem.resultMemoryContains(resulttuple))
{
nodemem.removeResultTuple(resulttuple);
propagateRemovalToTupleConsumers(resulttuple, state, mem, agenda);
}
// If constraints not passed and not in result -> nop
}
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_TUPLEADDED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
// System.out.println(nodemem);
}
/**
* Remove a tuple from this node.
* @param tuple The tuple.
*/
public void removeTuple(Tuple left, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
// if(getNodeId()==531)
// System.out.println("Remove tuple called: "+this+" "+left);
state.getProfiler().start(IProfiler.TYPE_NODE, this);
state.getProfiler().start(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_TUPLEREMOVED);
Tuple indextuple = createIndexTuple(state, left, mem);
CollectMemory nodemem = (CollectMemory)mem.getNodeMemory(this);
Tuple resulttuple = nodemem.getWorkingTuple(indextuple);
assert resulttuple!=null: "No working tuple found: "+indextuple;
Object val = left.getObject(tupleindex);
Set vals = (Set)resulttuple.getObject(tupleindex);
boolean removed = vals.remove(val);
// Remove tuple when last element is removed from set.
if(vals.isEmpty())
{
nodemem.removeWorkingTuple(indextuple);
if(nodemem.resultMemoryContains(resulttuple))
{
nodemem.removeResultTuple(resulttuple);
propagateRemovalToTupleConsumers(resulttuple, state, mem, agenda);
}
}
// Check constraints if at least one element.
else
{
assert removed: "Value not found in result tuple: "+val;
if(checkConstraints(resulttuple, state))
{
// If constraints passed and not in result -> add
if(!nodemem.resultMemoryContains(resulttuple))
{
nodemem.addResultTuple(resulttuple);
propagateAdditionToTupleConsumers(resulttuple, state, mem, agenda);
}
// If constraints passed and in result -> modify
else
{
// todo:
propagateModificationToTupleConsumers(resulttuple, null, null, resulttuple, state, mem, agenda);
}
}
else
{
// If constraints not passed and in result -> remove
if(nodemem.resultMemoryContains(resulttuple))
{
nodemem.removeResultTuple(resulttuple);
propagateRemovalToTupleConsumers(resulttuple, state, mem, agenda);
}
// If constraints not passed and not in result -> nop
}
}
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_TUPLEREMOVED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
// System.out.println(nodemem);
}
/**
* Modify a tuple in this node.
* @param left The tuple.
*/
public void modifyTuple(Tuple left, int tupleindex, OAVAttributeType type,
Object oldvalue, Object newvalue, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
// if(getNodeId()==531)
// System.out.println("Modify tuple called: "+this+" "+left);
if(!getRelevantAttributes().contains(type))
return;
// Problem: changed tuple could produce changed indextuple -> no identification of old value
Tuple indextuple = createIndexTuple(state, left, mem);
CollectMemory nodemem = (CollectMemory)mem.getNodeMemory(this);
Tuple resulttuple = nodemem.getWorkingTuple(indextuple);
assert resulttuple!=null: "No working tuple found: "+indextuple;
// Check if modification changes node memory.
boolean affected = isAffected(type);
if(affected)
{
boolean contains = nodemem.resultMemoryContains(resulttuple);
boolean check = checkConstraints(resulttuple, state);
// Object no longer valid -> remove
if(contains && !check)
{
nodemem.removeResultTuple(resulttuple);
propagateRemovalToTupleConsumers(resulttuple, state, mem, agenda);
}
// Tuple newly valid -> add
else if(!contains && check)
{
nodemem.addResultTuple(resulttuple);
propagateAdditionToTupleConsumers(resulttuple, state, mem, agenda);
}
else if(contains)
{
propagateModificationToTupleConsumers(resulttuple, type, oldvalue, newvalue,
state, mem, agenda);
}
}
else
{
// Tuple changed in memory -> propagate modification
boolean contains = nodemem.resultMemoryContains(resulttuple);
if(contains)
{
propagateModificationToTupleConsumers(resulttuple, type, oldvalue, newvalue,
state, mem, agenda);
}
}
state.getProfiler().start(IProfiler.TYPE_NODE, this);
state.getProfiler().start(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_TUPLEMODIFIED);
state.getProfiler().stop(IProfiler.TYPE_NODEEVENT, IProfiler.NODEEVENT_TUPLEMODIFIED);
state.getProfiler().stop(IProfiler.TYPE_NODE, this);
// System.out.println(nodemem);
}
/**
* Propagate an indirect object change to this node.
* @param object The changed object.
*/
public void modifyIndirectObject(Object object, OAVAttributeType type, Object oldvalue, Object newvalue, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
throw new UnsupportedOperationException("Unsupported method.");
}
/**
* Set the tuple source of this node.
* @param node The tuple source node.
*/
public void setTupleSource(ITupleSourceNode node)
{
this.tsource = node;
}
/**
* Get the tuple source of this node.
* @return The object source node.
*/
public ITupleSourceNode getTupleSource()
{
return tsource;
}
//-------- methods --------
/**
* Create the node memory.
* @param state The state.
* @return The node memory.
*/
public Object createNodeMemory(IOAVState state)
{
return new CollectMemory();
}
/**
* Get the evaluators.
* @return The evaluators.
*/
public IConstraintEvaluator[] getConstraintEvaluators()
{
return evaluators;
}
//-------- methods --------
/**
* Test if the node is affected from a modification.
* @param type The attribute type.
* @return True, if possibly affected.
*/
public boolean isAffected(OAVAttributeType attr)
{
boolean ret = false;
for(int i=0; !ret && evaluators!=null && i© 2015 - 2025 Weber Informatics LLC | Privacy Policy