
jadex.rules.rulesystem.rete.nodes.SplitNode Maven / Gradle / Ivy
package jadex.rules.rulesystem.rete.nodes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import jadex.commons.SReflect;
import jadex.rules.rulesystem.AbstractAgenda;
import jadex.rules.rulesystem.rete.extractors.AttributeSet;
import jadex.rules.rulesystem.rete.extractors.IValueExtractor;
import jadex.rules.state.IOAVState;
import jadex.rules.state.IProfiler;
import jadex.rules.state.OAVAttributeType;
/**
* A split node has the purpose of generating virtual facts
* for multislot bindings that use a non-multi variable or
* variable patterns.
*/
public class SplitNode extends AbstractNode implements IObjectConsumerNode, IObjectSourceNode
{
//-------- attributes --------
/** The constant for a multi variable. */
public static final String MULTI = "multi";
/** The constant for a single variable. */
public static final String SINGLE = "single";
/** The constant for a dummy multi variable. */
public static final String MULTI_DUMMY = "multi_dummy";
//-------- attributes --------
/** The object source. */
protected IObjectSourceNode osource;
/** The object consumers. */
protected IObjectConsumerNode[] oconsumers;
/** The set of relevant attributes. */
protected volatile AttributeSet relevants;
/** The set of indirect attributes. */
protected volatile AttributeSet indirects;
/** The values extractor. */
// Needed as long as multifield extractor is based on attribute
protected OAVAttributeType attr;
/** The values extractor. */
protected IValueExtractor extractor;
/** The splitpattern (multi, single or multi dummy). */
protected String[] splitpattern;
/** The minimum number of required values. */
protected int min_values;
//-------- constructors --------
/**
* Create a new node.
* @param state The state.
*/
public SplitNode(int nodeid, IValueExtractor extractor, OAVAttributeType attr, String[] splitpattern)
{
super(nodeid);
assert extractor!=null;
assert attr!=null;
assert !OAVAttributeType.NONE.equals(attr.getMultiplicity());
assert splitpattern.length>0;
this.extractor = extractor;
this.attr = attr;
this.min_values = 0;
for(int i=0; i0)
System.arraycopy(oconsumers, 0, tmp, 0, i);
if(i flattened multi-collection
ret = new ArrayList();
for(Iterator it=((Map)mem.getNodeMemory(this)).values().iterator(); it.hasNext(); )
ret.addAll((Collection)it.next());
}
return ret;
}
/**
* Get all object consumer nodes.
* @return All object consumer nodes.
*/
public IObjectConsumerNode[] getObjectConsumers()
{
return oconsumers;
}
//-------- methods --------
/**
* Create the node memory.
* @param state The state.
* @return The node memory.
*/
public Object createNodeMemory(IOAVState state)
{
return new LinkedHashMap();
}
//-------- helper methods --------
/**
* Propagate a new object to all object consumers.
* @param object The new object.
*/
protected void propagateAdditionToObjectConsumers(Object object, IOAVState state, ReteMemory mem, AbstractAgenda agenda)
{
IObjectConsumerNode[] ocon = oconsumers;
for(int i=0; ocon!=null && i=min_values)
generateBindings(values.length, 0, new int[splitpattern.length], object, values, ret);
return ret;
}
/**
* Generate all possible bindings for a list of values.
* @param weight The number of values to distribute on variables.
* @param cur The current variable number.
* @param binding Results are stored in this binding array (contains
* for each variable how many values it should store).
* @param values The values to distribute.
* @param ret The result list containing all found bindings (in form of virtual facts).
*/
protected void generateBindings(int weight, int cur, int[] binding, Object object,
Object[] values, List ret)
{
if(cur==binding.length-1)
{
binding[cur] = weight;
//System.out.println("Found binding: "+Srules.arrayToString(binding));
ret.add(generateVirtualFact(object, binding, values));
}
else
{
if(!splitpattern[cur].equals(SINGLE))
{
for(int i=0; i<=weight-min_values; i++)
{
binding[cur] = i;
generateBindings(weight-i, cur+1, binding, object, values, ret);
}
}
else
{
binding[cur] = 1;
generateBindings(weight-1, cur+1, binding, object, values, ret);
}
}
}
/**
* Generate a virtual fact for a found binding.
* @param binding The number of values for each variable.
* @param values The multislot values.
* @return A virtual fact with one binding.
*/
protected VirtualFact generateVirtualFact(Object object, int[] binding, Object[] values)
{
int off = 0;
int bcnt = 0;
List splitvals = new ArrayList();
for(int i=0; i1)
{
List vals = new ArrayList();
for(int j=off; j
© 2015 - 2025 Weber Informatics LLC | Privacy Policy