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

tyRuBa.engine.EagerImplementation Maven / Gradle / Ivy

package tyRuBa.engine;

import java.util.ArrayList;

import tyRuBa.engine.compilation.CompilationContext;
import tyRuBa.engine.compilation.Compiled;
import tyRuBa.engine.compilation.SemiDetCompiled;
import tyRuBa.modes.BindingList;
import tyRuBa.modes.Factory;
import tyRuBa.modes.Mode;
import tyRuBa.modes.ModeCheckContext;
import tyRuBa.modes.Multiplicity;
import tyRuBa.modes.PredInfoProvider;
import tyRuBa.modes.PredicateMode;
import tyRuBa.modes.TupleType;
import tyRuBa.modes.TypeModeError;
import tyRuBa.util.ElementSource;

/**
 * An Implementation is used in defining NativePredicates; it implements
 * how results are evaluated in a certain predicate mode 
 */

public abstract class EagerImplementation extends AbstractImplementation {
	
	private ArrayList solutions = null;
	private ArrayList arguments;
	private ArrayList results;
	private RBTuple argsAndResults;
		
	/** calculates result and calls addSolution to store the results */
	public abstract void doit(RBTerm[] args);
	
	public EagerImplementation(String paramModesString, String modeString) {
		this(Factory.makePredicateMode(paramModesString, modeString));
	}
	
	public EagerImplementation(String paramModesString, Mode mode) {
		this(Factory.makePredicateMode(
				BindingList.convertFromString(paramModesString), 
				mode));
	}
	
	public EagerImplementation(PredicateMode mode) {
		super(mode);
		BindingList bindings = mode.getParamModes();
		ArrayList argsAndRes = new ArrayList();
		arguments = new ArrayList();
		results = new ArrayList();
		for (int i = 0; i < bindings.size(); i++) {
			RBTerm curr = FrontEnd.makeUniqueVar("arg" + i);
			argsAndRes.add(curr);
			if (bindings.get(i).isBound()) {
				arguments.add(curr); 
			} else {
				results.add(curr);
			}
		}		
		argsAndResults = RBTuple.make(argsAndRes);
	}
		
	public RBTerm getArgAt(int i) {
		return (RBTerm) arguments.get(i);
	}
	
	public int getNumArgs() {
		return arguments.size();
	}
	
	public RBTerm getResultAt(int i) {
		return (RBTerm) results.get(i);
	}
	
	public RBTuple getArgs() {
		return argsAndResults;
	}
	
	public void addSolution() {
		solutions.add(new RBTerm[0]);
	}

	public void addSolution(Object o) {
		solutions.add(new RBTerm[] {RBCompoundTerm.makeJava(o)} );
	}

	public void addSolution(Object o1, Object o2) {
		solutions.add(new RBTerm[] {RBCompoundTerm.makeJava(o1), RBCompoundTerm.makeJava(o2)});
	}

	public void addSolution(Object... objs) {
		RBTerm[] terms = new RBTerm[objs.length];
		for (int i = 0; i < objs.length; i++) {
			terms[i] = RBCompoundTerm.makeJava(objs[i]);
		}
		solutions.add(terms);
	}
	
	public void addTermSolution(RBTerm t) {
		solutions.add(new RBTerm[] {t} );
	}

	public void addTermSolution(RBTerm t1, RBTerm t2) {
		solutions.add(new RBTerm[] {t1,t2} );
	}
		
	public ArrayList eval(RBContext rb, final Frame f, final Frame callFrame) {
		solutions = new ArrayList();
		RBTerm[] args = new RBTerm[getNumArgs()];
		for (int i = 0; i < getNumArgs(); i++) {
			args[i] = getArgAt(i).substitute(f);
		}
		try {
			doit(args);
		} catch (ClassCastException e) {
			//ignore. We silently Convert runtime type errors into 'no result'. 
		}
		ArrayList results = new ArrayList();
		for (int i = 0; i < solutions.size(); i++) {
			Frame result = (Frame) f.clone();
			RBTerm[] sols = (RBTerm[]) solutions.get(i);
			for(int j = 0; j < sols.length; j++) {
				result = getResultAt(j).substitute(result).unify(sols[j], result);
				if (result == null) {
					j = sols.length;
				}
			}
			if (result != null) {
				results.add(callFrame.callResult(result));
			}
		}
		return results;
	}
	
	@Override
	public Compiled compile(CompilationContext c) {
		if (getMode().hi.compareTo(Multiplicity.one) <= 0) {
			return new SemiDetCompiled() {
				public Frame runSemiDet(Object input, RBContext context) {
					Frame callFrame = new Frame();
					RBTuple goal = 
						(RBTuple) ((RBTuple)input).instantiate(callFrame);
					final Frame fc = goal.unify(getArgs(), new Frame());
					ArrayList results = eval(context, fc, callFrame);
					if (results.size() == 0) {
						return null;
					} else {
						return (Frame)results.get(0);
					}
				}
			};
		} else {
			return new Compiled(getMode()) {
				public ElementSource runNonDet(Object input, RBContext context) {
					final Frame callFrame = new Frame();
					final RBTuple goal = 
						(RBTuple) ((RBTuple)input).instantiate(callFrame);
					final Frame fc = goal.unify(getArgs(), new Frame());
					ArrayList results = eval(context, fc, callFrame);
					if (results == null) {
						return ElementSource.theEmpty;
					} else {
						return ElementSource.with(results);
					}
				}
			};
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy