All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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