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

jadex.rules.rulesystem.rete.nodes.SplitNode Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 2.4
Show newest version
package jadex.rules.rulesystem.rete.nodes;

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;

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;

/**
 *  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 String MULTI = "multi";
	
	/** The constant for a single variable. */
	public static String SINGLE = "single";

	/** The constant for a dummy multi variable. */
	public static String MULTI_DUMMY = "multi_dummy";
	
	//-------- attributes --------
	
	/** The object source. */
	protected IObjectSourceNode osource;
	
	/** The object consumers. */
	protected IObjectConsumerNode[]	oconsumers;

	/** The set of relevant attributes. */
	protected AttributeSet relevants;
	
	/** The set of indirect attributes. */
	protected 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]!=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 - 2024 Weber Informatics LLC | Privacy Policy