package org.jactr.core.module.procedural.six.learning; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javolution.util.FastList; import org.jactr.core.module.procedural.six.learning.DefaultProductionCompiler6.BufferStruct; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.module.procedural.five.learning.ICompilableBuffer; import org.jactr.core.module.procedural.five.learning.ICompilableContext; import org.jactr.core.production.VariableBindings; import org.jactr.core.production.action.AddAction; import org.jactr.core.production.action.IAction; import org.jactr.core.production.action.ModifyAction; import org.jactr.core.production.action.RemoveAction; import org.jactr.core.production.action.SetAction; import org.jactr.core.production.condition.ChunkCondition; import org.jactr.core.production.condition.ChunkTypeCondition; import org.jactr.core.production.condition.ICondition; import org.jactr.core.production.condition.QueryCondition; import org.jactr.core.production.condition.VariableCondition; import org.jactr.core.production.request.IRequest; import org.jactr.core.slot.IConditionalSlot; import org.jactr.core.slot.ISlot; import org.jactr.core.slot.ISlotContainer; public class ProductionCompilerEvaluator { static private final transient Log LOGGER = LogFactory.getLog(ProductionCompilerEvaluator.class); public static Integer empty = 0; public static Integer match = 8; public static Integer query = 16; public static Integer modify = 1; public static Integer add = 4; public static Integer remove = 2; public static Integer[] bufferActions = {empty, match, query, modify, add, remove}; private Evaluator[][] simpleEvaluatorTable; private Evaluator[][] retrievalEvaluatorTable; private Evaluator[][] perceptualEvaluatorTable; private Mapper[][] simpleMapperTable; private Mapper[][] retrievalMapperTable; private Mapper[][] perceptualMapperTable; private Collapser[][] simpleCollapserTable; private Collapser[][] retrievalCollapserTable; private Collapser[][] perceptualCollapserTable; ProductionCompilerEvaluator() { initializeMaps(bufferActions); } //simple type: immediate, deterministic, can't jam ( so can have two requests in a row ) and can't compile out private boolean isSimpleType(ICompilableContext context, IRequest req) { if(context.isImmediate(req) && context.isDeterministic(req) && !context.isJammable(req) && !context.canCompileOut(req)) return true; return false; } private boolean isRetrievalTypeBuffer(ICompilableContext context, IRequest req) { if(!context.isImmediate(req) && !context.isDeterministic(req) && !context.isJammable(req) && context.canCompileOut(req)) return true; return false; } private boolean isPerceptualTypeBuffer(ICompilableContext context, IRequest req) { if(!context.isImmediate(req) && !context.isDeterministic(req) && context.isJammable(req) && !context.canCompileOut(req)) return true; return false; } public boolean canCompile(BufferStruct one, BufferStruct two, ICompilableBuffer buffer) { LOGGER.debug("indices are " + one.index + " and " + two.index); if(isSimpleType(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking goal type compilation map for indices " + one.index + "," + two.index); return simpleEvaluatorTable[one.index][two.index].canCompile(one, two, buffer.getName()); } if(isRetrievalTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking retrieval type compilation map for indices " + one.index + "," + two.index); return retrievalEvaluatorTable[one.index][two.index].canCompile(one, two, buffer.getName()); } if(isPerceptualTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking perceptual type compilation map for indices " + one.index + "," + two.index); return perceptualEvaluatorTable[one.index][two.index].canCompile(one, two, buffer.getName()); } return false; } public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, ICompilableBuffer buffer) { if(isSimpleType(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking goal type mapper table for indices " + one.index + "," + two.index); return simpleMapperTable[one.index][two.index].extractMap(one, two, buffer.getName()); } if(isRetrievalTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking retrieval type compilation map for indices " + one.index + "," + two.index); return retrievalMapperTable[one.index][two.index].extractMap(one, two, buffer.getName()); } if(isPerceptualTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { //LOGGER.debug("checking perceptual type compilation map for indices " + one.index + "," + two.index); return perceptualMapperTable[one.index][two.index].extractMap(one, two, buffer.getName()); } return null; } public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, ICompilableBuffer buffer) { if(isSimpleType(buffer.getCompilableContext(), one.getIRequest())) { return simpleCollapserTable[one.index][two.index].collapseBuffer(one, two, buffer.getName()); } if(isRetrievalTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { return retrievalCollapserTable[one.index][two.index].collapseBuffer(one, two, buffer.getName()); } if(isPerceptualTypeBuffer(buffer.getCompilableContext(), one.getIRequest())) { return perceptualCollapserTable[one.index][two.index].collapseBuffer(one, two, buffer.getName()); } return null; } //define this class for evaluator functions; if you need to extend buffers/actions, can subclass off of ProductionCompilerEvaluator and just ProductionCompiler6.add more of these. protected abstract static class Evaluator { public abstract boolean canCompile(BufferStruct one, BufferStruct two, String bufferName); static public Evaluator TRUE = new Evaluator(){ public boolean canCompile(BufferStruct one, BufferStruct two, String bufferName) { //LOGGER.debug("Evaluator returning true by default."); return true; } }; static public Evaluator FALSE = new Evaluator(){ public boolean canCompile(BufferStruct one, BufferStruct two, String bufferName) { //LOGGER.debug("Evaluator returning false by default."); return false; } }; } //this class provides mappings from the variables of the first production to the variables/values of the second on a per-buffer basis. protected abstract static class Mapper { public abstract Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName); static public Mapper ERROR = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { return null; } }; static public Mapper EMPTY = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { return new HashMap<String, Object>(); } }; static public Map<String, Object> match(Collection<? extends ISlot> slots1, Collection<? extends ISlot> slots2, VariableBindings instantiationTwo) { Map<String, Object> map = new HashMap<String, Object>(); for(ISlot s2 : slots2) { for(ISlot s1 : slots1) { //LOGGER.debug("Mapper.match comparing " + s2 + ", " + s1); if(s1.getName().equals(s2.getName()) && ((IConditionalSlot)s1).getCondition() == ((IConditionalSlot)s2).getCondition()) { if(s2.isVariableValue()) { map.put(s2.getValue().toString(), s1.getValue()); } else if(s1.isVariableValue()) { map.put(s1.getValue().toString(), s2.getValue()); } else { //don't map, neither is a variable. } } } } return map; } } protected abstract static class Collapser { public abstract BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName); static public Collapser ERROR = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { return null; } }; static public Collapser EMPTY = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { return new BufferStruct(bufferName, one.hasStrictHarvesting(), null); } }; static public void findQueryCondition(BufferStruct one, BufferStruct two, BufferStruct newStruct) { boolean addAction = false; ICondition secondQuery = null; for(ICondition c : one.getConditions()) { if(c instanceof QueryCondition) { newStruct.conditions.add(clone(c)); return; } if(c instanceof AddAction) addAction = true; } //now, query in #2 and whether there is add in #2 if(addAction) return; for(ICondition c : two.getConditions()) { if(c instanceof QueryCondition) { secondQuery = c; } } // at this point we know whether there is an add action/query in #2 and that there is def. not a query in buffer one. if(secondQuery == null) return; //now, def. no add action and no query condition in #1 but query condition in #2 newStruct.conditions.add(clone(secondQuery)); } //s1 - s2 (by slot name) //adds all slots in s1 that are not in s2 to the result static FastList<ISlot> slots = new FastList<ISlot>(); static public boolean minusSlots(ISlotContainer sc1, ISlotContainer sc2, ISlotContainer result) { slots.clear(); if(sc1 != null) sc1.getSlots(slots); for(ISlot s1 : slots) { boolean mentioned = false; if(sc2 != null) { for(ISlot s2 : sc2.getSlots()) { if(((IConditionalSlot)s2).getCondition() != IConditionalSlot.EQUALS) { LOGGER.warn("Encountered unexpected case where action assignment function is not equals... not compiling " + sc1); return false; } if(s1.getName().equals(s2.getName()) && ((IConditionalSlot)s1).getCondition() == IConditionalSlot.EQUALS) { //both are equals functions. match up variables. mentioned = true; } } } if(!mentioned) result.addSlot(s1); } return true; } //adds all slots that are in sc1 that aren't in sc2 to sc2 static public boolean unionSlots(ISlotContainer sc1, ISlotContainer sc2) { slots.clear(); if(sc1 == null) return true; sc2.getSlots(slots); //sc2 should never be null for(ISlot s1 : sc1.getSlots()) { boolean matched = false; for(ISlot s2 : slots) { if(s1.getName().equals(s2.getName()) && ((IConditionalSlot)s1).getCondition() == IConditionalSlot.EQUALS && s1.getValue().equals(s2.getValue())) { matched = true; } } if(!matched) sc2.addSlot(s1); } return true; } static public boolean calcNewCondition(ISlotContainer c1, ISlotContainer c2, ISlotContainer a1, ISlotContainer newCondition) { //According to ACT-R, newC = C1 + (C2 - A1) if(!minusSlots(c2, a1, newCondition)) return false; //LOGGER.debug("Conditions one is " + c1 + " and two is " + c2+ " and slots is " + slots); if(!unionSlots(c1, newCondition)) return false; //for(ISlot s : slots) newCondition.addSlot(s); //LOGGER.debug("Found new condition " + newCondition); return true; } static public boolean calcNewAction(ISlotContainer a1, ISlotContainer a2, ISlotContainer newAction) { // newA = A1 overwritten by A2 //LOGGER.debug("calculating new action from " + a1.getSlots() + " and " + a2.getSlots()); slots.clear(); a2.getSlots(slots); for(ISlot s : slots) newAction.addSlot(s); //LOGGER.debug("slots from second action are " + newAction.getSlots()); if(minusSlots(a1, a2, newAction)) { //LOGGER.debug(" and once added in from first action " + newAction.getSlots()); return true; } return false; } static public BufferStruct cloneProduction(BufferStruct toClone, String bufferName) { BufferStruct newStruct = new BufferStruct(bufferName, toClone.hasStrictHarvesting(), toClone.getVariableBindings()); for(ICondition condition : toClone.getConditions()) { ICondition cloned = clone(condition); if(cloned != null) newStruct.conditions.add(cloned); else return null; } for(IAction action : toClone.getActions()) { IAction cloned = clone(action); if(cloned != null) newStruct.actions.add(cloned); else return null; } return newStruct; } //clones a condition so that the arraylist of slots is a different object. //doesn't create new slot objects. static public ICondition clone(ICondition condition) { if(condition instanceof QueryCondition) { return ((QueryCondition)condition).clone(); } else if (condition instanceof VariableCondition) { return new VariableCondition(((VariableCondition)condition).getBufferName(), ((VariableCondition)condition).getVariableName()); } else if (condition instanceof ChunkTypeCondition && !(condition instanceof ChunkCondition)) { return new ChunkTypeCondition(((ChunkTypeCondition)condition).getBufferName(), ((ChunkTypeCondition)condition).getChunkType(), ((ChunkTypeCondition)condition).getSlots()); } else { LOGGER.debug("don't know how to clone/handle condition of instance " + condition); return null; } } //clones an action so that the arraylist of slots is a different object. //doesn't create new slot objects. static public IAction clone(IAction action) { if(action instanceof RemoveAction) { return new RemoveAction(((RemoveAction)action).getBufferName()); } else if (action instanceof ModifyAction) { return new ModifyAction(((ModifyAction)action).getBufferName(), ((ModifyAction)action).getSlots()); } else if (action instanceof AddAction) { return new AddAction(((AddAction)action).getBufferName(), ((AddAction)action).getReferant(), ((AddAction)action).getSlots()); } else if (action instanceof SetAction){ return new SetAction(((SetAction)action).getBufferName(), ((SetAction)action).getReferant(), ((SetAction)action).getSlots()); } else { LOGGER.debug("don't know how to clone/handle action of instance " + action); return null; } } } //FIXME: needs to check across ALL buffers, not just this one. static public Evaluator no_rhs_reference = new Evaluator(){ public boolean canCompile(BufferStruct one, BufferStruct two, String bufferName) { //can't compile if the buffer variable is used on the RHS of p2 for(IAction action : two.getActions()) { if(action instanceof ModifyAction) { for(ISlot s : ((ModifyAction)action).getSlots()) { if(s.getValue().toString().equals("="+bufferName)) { LOGGER.debug("Evaluator no_rhs_reference returning false because of action " + action + " and slot " + s); return false; } } } else if (action instanceof AddAction) { if (((AddAction)action).getReferant().toString().equals("="+bufferName)) return false; for(ISlot s : ((AddAction)action).getSlots()) { if(s.getValue().toString().equals("="+bufferName)) { LOGGER.debug("Evaluator no_rhs_reference returning false because of action " + action + " and slot " + s); return false; } } } else if(action instanceof SetAction) { if (((SetAction)action).getReferant().toString().equals("="+bufferName)) return false; for(ISlot s : ((SetAction)action).getSlots()) { if(s.getValue().toString().equals("="+bufferName)) { LOGGER.debug("Evaluator no_rhs_reference returning false because of action " + action + " and slot " + s); return false; } } } //don't need to do RemoveAction separately because it subclassess off of ModifyAction } return true; } }; static public Evaluator p2_busy_or_empty = new Evaluator(){ public boolean canCompile(BufferStruct one, BufferStruct two, String bufferName) { //second production ProductionCompiler6.query must be "state busy" or "buffer ProductionCompiler6.empty" for(ICondition condition : two.getConditions()) { if (condition instanceof QueryCondition && ((QueryCondition) condition).getBufferName().equals(bufferName)) { for(ISlot s : ((QueryCondition) condition).getSlots()) { if(s.getName().equals("state")) { if(!s.getValue().toString().equals("busy")) { LOGGER.debug("Evaluator busy_or_ProductionCompiler6.empty returning false because of condition " + condition + " and slot " + s); return false; } } else if(s.getName().equals("buffer")) { if(!s.getValue().toString().equals("ProductionCompiler6.empty")) { LOGGER.debug("Evaluator busy_or_ProductionCompiler6.empty returning false because of condition " + condition + " and slot " + s); return false; } } else { LOGGER.debug("Evaluator busy_or_ProductionCompiler6.empty returning false because of condition " + condition + " and slot " + s); return false; } } } } return false; } }; static public Evaluator same_queries = new Evaluator(){ public boolean canCompile(BufferStruct one, BufferStruct two, String bufferName) { //both queries must be the same. ArrayList<ISlot> query1 = new ArrayList<ISlot>(); ArrayList<ISlot> query2 = new ArrayList<ISlot>(); for(ICondition condition : one.getConditions()) { if (condition instanceof QueryCondition && ((QueryCondition) condition).getBufferName().equals(bufferName)) { query1.addAll(((QueryCondition) condition).getSlots()); } } for(ICondition condition : two.getConditions()) { if (condition instanceof QueryCondition && ((QueryCondition) condition).getBufferName().equals(bufferName)) { query2.addAll(((QueryCondition) condition).getSlots()); } } for(ISlot s1 : query1) { for(ISlot s2 : query2) { if(s1.getName().equals(s2.getName()) && s1.equalValues(s2)) { query2.remove(s2); break; //break out of loop to advance to the next s1 } } //if we get here, no ProductionCompiler6.match!! LOGGER.debug("Evaluator same_queries returning false because of unmatched slot " + s1 + " from production one"); return false; } if(query2.size() > 0) { LOGGER.debug("Evaluator same_queries returning false because of unmatched slot(s) " + query2 + " from production two"); return false; //unProductionCompiler6.matched item in ProductionCompiler6.query2 } return true; } }; /* @Deprecated //should be handeled by mapper_no_add_p1... static public Mapper mapper_match_and_match = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { //just match the variables from the conditions of the first one to the conditions of the second one. if(one.getConditions().size() > 1 || two.getConditions().size() > 1) { LOGGER.warn("Should not be here in ProductionCompilerEvaluator.Mapper.matches_and_match; more than one condition for one of the productions." + one.getConditions() + "," + two.getConditions()); return null; } return Mapper.match(((ISlotContainer)one.conditions.iterator().next()).getSlots(), ((ISlotContainer)two.conditions.iterator().next()).getSlots(), two.getVariableBindings()); } };*/ //TODO: this (and others) assumes no remove. but I guess that is reasonable in this case, otherwise wouldn't need mapping. static public Mapper mapper_no_add_p1 = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { if(one.getConditions().size() > 1 || one.getActions().size() > 1 || two.getConditions().size() > 1) { LOGGER.warn("Should not be here in ProductionCompilerEvaluator.Mapper.match_no_add_p1; more than one condition or action for one of the productions." + one.getConditions() + "," + one.getActions() + "," + two.getConditions()); return null; } //fold conditions into actions for a good snapshot if(one.conditions.size() > 0 && one.actions.size() > 0) { if(!Collapser.minusSlots(((ISlotContainer)one.conditions.iterator().next()), ((ISlotContainer)one.actions.iterator().next()), ((ISlotContainer)one.actions.iterator().next()))) return null; return Mapper.match(((ISlotContainer)one.actions.iterator().next()).getSlots(), ((ISlotContainer)two.conditions.iterator().next()).getSlots(), two.getVariableBindings()); } else if(one.conditions.size() > 0) { //if only condition in first production return Mapper.match(((ISlotContainer)one.conditions.iterator().next()).getSlots(), ((ISlotContainer)two.conditions.iterator().next()).getSlots(), two.getVariableBindings()); } else { //only action in first production LOGGER.warn("Should not be here in ProductionCompilerEvaluator.Mapper.match_no_add_p1 - only actions (not conditions) p1, yet not an add?"); return null; } } }; static public Mapper mapper_add_p1 = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { ICondition conditionTwo = null; for(ICondition condition : two.getConditions()) { if(!(condition instanceof QueryCondition)) { if(conditionTwo != null) { LOGGER.warn("somehow got to mapper_add_p1 incorrectly... more than one non-query conditionTwo " + two.getConditions()); return null; } conditionTwo = condition; } } ISlotContainer add1 = null; for(IAction a1 : one.getActions()) { if(a1 instanceof AddAction) { add1 = (ISlotContainer) a1; break; } } if(add1 == null) { LOGGER.warn("Should not be here in ProductionCompilerEvaluator.Mapper.match_add_p1; no add action." + one.getConditions() + "," + one.getActions() + "," + two.getConditions()); return null; } else { return Mapper.match(add1.getSlots(), ((ISlotContainer)conditionTwo).getSlots(), two.getVariableBindings()); } } }; //Not sure this needs to be different from mapper_add_p1, but it is in lisp's ACT-R documentation, so I'll leave it for now. static public Mapper mapper_nondeterministic_add_p1 = new Mapper() { public Map<String, Object> extractMap(BufferStruct one, BufferStruct two, String bufferName) { //need to relate add action, chunk retrieved, and match condition Map<String, Object> map = new HashMap<String, Object>(); for(IAction a : one.getActions()) { if(a instanceof AddAction) { for(ISlot s : ((AddAction)a).getSlots()) { if(s.getName().toString().startsWith("=")) { LOGGER.warn("variable slot name in retrieval add action; can't handle " + a + "," + s); return null; } if(s.isVariableValue()) { map.put(s.getValue().toString(), one.bindings.get(s.getValue().toString())); } } } } for(ICondition c : two.getConditions()) { if(c instanceof ChunkTypeCondition) { for(ISlot s : ((ChunkTypeCondition)c).getSlots()) { if(s.isVariableValue()) { map.put(s.getValue().toString(), two.bindings.get(s.getValue().toString())); } } } } return map; } }; //things like [match][match+modify] or [match+modify][match+modify+add] static public Collapser collapse_no_add_p1 = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { BufferStruct newStruct = new BufferStruct(bufferName, one.hasStrictHarvesting(), null); findQueryCondition(one, two, newStruct); ICondition conditionOne = null; ICondition conditionTwo = null; for(ICondition condition : one.getConditions()) { if(!(condition instanceof QueryCondition)) { if(conditionOne != null) { LOGGER.warn("something is wrong in collapse_no_add_in_p1... more than one non-query conditionOne."); return null; } conditionOne = condition; } } for(ICondition condition : two.getConditions()) { if(!(condition instanceof QueryCondition)) { if(conditionTwo != null) { LOGGER.warn("something is wrong in collapse_no_add_in_p1... more than one non-query conditionTwo."); return null; } conditionTwo = condition; } } if(one.getActions().size() > 2) { LOGGER.warn("something is wrong in collapse_no_add_in_p1... more than two actionOnes (and we know there is no add)."); return null; } if(one.getActions().size() > 0) { //LOGGER.debug("Conditions one is " + one.getConditions() + " and two is " + two.getConditions()); if(conditionOne != null || conditionTwo != null) { ChunkTypeCondition match = new ChunkTypeCondition(bufferName, ((ChunkTypeCondition)conditionOne).getChunkType()); if(!calcNewCondition((ISlotContainer)conditionOne, (ISlotContainer)conditionTwo, (ISlotContainer)one.getActions().iterator().next(), match)) return null; newStruct.conditions.add(match); } for(IAction a1 : one.getActions()) { if(a1 instanceof ModifyAction) { boolean modded = false; for(IAction a2 : two.getActions()) { if(a2 instanceof ModifyAction) { modded = true; ModifyAction mod = new ModifyAction(bufferName); if(!calcNewAction((ISlotContainer)a1, (ISlotContainer)a2, mod)) return null; newStruct.actions.add(mod); } else { newStruct.actions.add(clone(a2)); } } if(!modded) newStruct.actions.add(clone(a1)); } else if(a1 instanceof RemoveAction) { newStruct.actions.add(clone(a1)); } else { LOGGER.warn("uncaught case - something other than a modify (and we know it's not an add) in production one's action " + one.getActions()); return null; } } } else { //LOGGER.debug("Conditions one is " + one.getConditions() + " and two is " + two.getConditions()); if(conditionOne != null || conditionTwo != null) { ChunkTypeCondition match = (conditionOne != null ? new ChunkTypeCondition(bufferName, ((ChunkTypeCondition)conditionOne).getChunkType()) : new ChunkTypeCondition(bufferName, ((ChunkTypeCondition)conditionTwo).getChunkType())); if(!calcNewCondition((ISlotContainer)conditionOne, (ISlotContainer)conditionTwo, null, match)) return null; newStruct.conditions.add(match); } for(IAction a2 : two.getActions()) { newStruct.actions.add(clone(a2)); } } return newStruct; } }; //we can assume this won't ever get called if strict harvesting is relevant / enabled. static public Collapser collapse_add_p1 = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { BufferStruct newStruct = new BufferStruct(bufferName, one.hasStrictHarvesting(), null); findQueryCondition(one, two, newStruct); for(ICondition condition : one.getConditions()) { if(!(condition instanceof QueryCondition)) { newStruct.getConditions().add(clone(condition)); } } AddAction plusOne = null; IAction modTwo = null; for(IAction action : one.getActions()) { if(action instanceof ModifyAction) { newStruct.getActions().add(clone(action)); } else if (action instanceof AddAction) { plusOne = (AddAction) action; } } for(IAction action : two.getActions()) { if(action instanceof ModifyAction) { modTwo = action; } else { LOGGER.warn("encountered unhandled case of non-modify action " + action); return null; } } if(plusOne == null) { LOGGER.warn("encountered unhandled case of no plus case in p1 " + one.getActions()); return null; } if(modTwo != null) { AddAction add = new AddAction(bufferName, plusOne.getChunkType()); if(!calcNewAction((ISlotContainer)plusOne, (ISlotContainer)modTwo, add)) return null; newStruct.actions.add(add); } else { newStruct.getActions().add(clone(plusOne)); } return newStruct; } }; /* @Deprecated static public Collapser collapse_add_p1_check_sh = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { if(one.hasStrictHarvesting()) { for(Iterator<IAction> it = one.getActions().iterator(); it.hasNext(); ) { IAction action = it.next(); if(action instanceof AddAction) { it.remove(); } } two.getActions().add(new RemoveAction(bufferName)); return collapse_no_add_p1.collapseBuffer(one, two, bufferName); } else return collapse_add_p1.collapseBuffer(one, two, bufferName); } };*/ /* @Deprecated //sh stands for "strict harvesting //according to tony, this is deprecated static public Collapser collapse_no_add_p1_check_sh = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { if(one.hasStrictHarvesting()) { one.getActions().add(new RemoveAction(bufferName)); } return collapse_no_add_p1.collapseBuffer(one, two, bufferName); } };*/ /* @Deprecated //if something in retrieval from our add, and no strict harvesting, we can't combine static public Collapser collapse_retrieval_add_p1_check_sh = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { if(!one.hasStrictHarvesting()) return null; return collapse_nondeterministic_add_p1.collapseBuffer(one, two, bufferName); } };*/ static public Collapser collapse_compileout_add_p1 = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { BufferStruct newStruct = new BufferStruct(bufferName, one.hasStrictHarvesting(), null); findQueryCondition(one, two, newStruct); for(ICondition c : one.getConditions()) { if(!(c instanceof QueryCondition)) { newStruct.conditions.add(clone(c)); } } //exclude modify actions for(IAction a : two.getActions()) { if(a instanceof ModifyAction && !(a instanceof RemoveAction)) { LOGGER.warn("Encountered a modify action in action 2 when collapsing retrieval buffer - this is illegal." + two.getActions() + "," + a); return null; } else if (a instanceof AddAction || a instanceof RemoveAction) { newStruct.actions.add(clone(a)); } } return newStruct; } }; //p2 is fired before chunk is actually retrieved //p2 has a query or nothing, p1 has an add and whatever else. static public Collapser collapse_nonimmediate_add_p1_not_harvested = new Collapser() { public BufferStruct collapseBuffer(BufferStruct one, BufferStruct two, String bufferName) { BufferStruct newStruct = new BufferStruct(bufferName, one.hasStrictHarvesting(), null); for(ICondition condition : two.getConditions()) { if(!(condition instanceof QueryCondition)) { LOGGER.warn("somehow got to collapse_retrieval_add_p1_not_harvested incorrectly... got a non-query conditionTwo " + two.getConditions()); return null; } } findQueryCondition(one, two, newStruct); for(ICondition c : one.getConditions()) { if(!(c instanceof QueryCondition)) { newStruct.conditions.add(clone(c)); } } for(IAction a : one.getActions()) { if (a instanceof AddAction) { newStruct.actions.add(clone(a)); } } return newStruct; } }; private void initializeMaps(Integer bufferActions[]) { //initialize all values to false, just in case simpleEvaluatorTable = new Evaluator[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; retrievalEvaluatorTable = new Evaluator[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; perceptualEvaluatorTable = new Evaluator[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; simpleMapperTable = new Mapper[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; retrievalMapperTable = new Mapper[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; perceptualMapperTable = new Mapper[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; simpleCollapserTable = new Collapser[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; retrievalCollapserTable = new Collapser[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; perceptualCollapserTable = new Collapser[(int) (Math.pow(2,(bufferActions.length))-1)][(int) Math.pow(2,(bufferActions.length))-1]; for(int i = 0; i < Math.pow(2,(bufferActions.length))-1; i++) { for(int j = 0; j < Math.pow(2,(bufferActions.length))-1; j++) { simpleEvaluatorTable[i][j] = Evaluator.FALSE; retrievalEvaluatorTable[i][j] = Evaluator.FALSE; perceptualEvaluatorTable[i][j] = Evaluator.FALSE; simpleMapperTable[i][j] = Mapper.ERROR; retrievalMapperTable[i][j] = Mapper.ERROR; perceptualMapperTable[i][j] = Mapper.ERROR; simpleCollapserTable[i][j] = Collapser.ERROR; retrievalCollapserTable[i][j] = Collapser.ERROR; perceptualCollapserTable[i][j] = Collapser.ERROR; } } //collapse equivalent rows/columns to save time Object[][][] tableArray = {simpleEvaluatorTable, simpleMapperTable, simpleCollapserTable, retrievalEvaluatorTable, retrievalMapperTable, retrievalCollapserTable, perceptualEvaluatorTable, perceptualMapperTable, perceptualCollapserTable}; for(int i = 0; i < tableArray.length; i++) { //first do rows tableArray[i][add+remove] = tableArray[i][add]; tableArray[i][match+add+remove] = tableArray[i][match+add]; tableArray[i][match+modify+add+remove] = tableArray[i][match+modify+add]; tableArray[i][query+add+remove] = tableArray[i][query+add]; tableArray[i][match+query+add+remove] = tableArray[i][match+query+add]; tableArray[i][match+query+modify+remove+add] = tableArray[i][match+query+modify+add]; //now columns for(int j = 0; j <Math.pow(2, bufferActions.length)-1; j++) { tableArray[i][j][add+remove] = tableArray[i][j][add]; tableArray[i][j][match+add+remove] = tableArray[i][j][match+add]; tableArray[i][j][match+modify+add+remove] = tableArray[i][j][match+modify+add]; tableArray[i][j][query+add+remove] = tableArray[i][j][query+add]; tableArray[i][j][match+query+add+remove] = tableArray[i][j][match+query+add]; tableArray[i][j][match+query+modify+remove+add] = tableArray[i][j][match+query+modify+add]; } } //now begins the long, arduous process of filling these in... not the prettiest way of doing it, //but sure makes readability/understanding much better. simpleEvaluatorTable[empty][match] = Evaluator.TRUE; simpleEvaluatorTable[empty][add] = Evaluator.TRUE; simpleEvaluatorTable[empty][remove] = Evaluator.TRUE; simpleEvaluatorTable[empty][match+modify] = Evaluator.TRUE; simpleEvaluatorTable[empty][match+add] = Evaluator.TRUE; simpleEvaluatorTable[empty][match+modify+add] = Evaluator.TRUE; simpleMapperTable[empty][match] = Mapper.EMPTY; simpleMapperTable[empty][add] = Mapper.EMPTY; simpleMapperTable[empty][remove] = Mapper.EMPTY; simpleMapperTable[empty][match+modify] = Mapper.EMPTY; simpleMapperTable[empty][match+add] = Mapper.EMPTY; simpleMapperTable[empty][match+modify+add] = Mapper.EMPTY; simpleCollapserTable[empty][match] = collapse_no_add_p1; simpleCollapserTable[empty][add] = collapse_no_add_p1; simpleCollapserTable[empty][remove] = collapse_no_add_p1; simpleCollapserTable[empty][match+modify] = collapse_no_add_p1; simpleCollapserTable[empty][match+add] = collapse_no_add_p1; simpleCollapserTable[empty][match+modify+add] = collapse_no_add_p1; simpleEvaluatorTable[match][empty] = Evaluator.TRUE; simpleEvaluatorTable[match][match] = Evaluator.TRUE; simpleEvaluatorTable[match][add] = Evaluator.TRUE; simpleEvaluatorTable[match][remove] = Evaluator.TRUE; simpleEvaluatorTable[match][match+modify] = Evaluator.TRUE; //tested simpleEvaluatorTable[match][match+add] = Evaluator.TRUE; simpleEvaluatorTable[match][match+remove] = Evaluator.TRUE; simpleEvaluatorTable[match][match+modify+add] = Evaluator.TRUE; simpleMapperTable[match][empty] = Mapper.EMPTY; simpleMapperTable[match][match] = mapper_no_add_p1; simpleMapperTable[match][add] = Mapper.EMPTY; simpleMapperTable[match][remove] = Mapper.EMPTY; simpleMapperTable[match][match+modify] = mapper_no_add_p1; //tested simpleMapperTable[match][match+add] = mapper_no_add_p1; simpleMapperTable[match][match+remove] = mapper_no_add_p1; simpleMapperTable[match][match+modify+add] = mapper_no_add_p1; simpleCollapserTable[match][empty] = collapse_no_add_p1; simpleCollapserTable[match][match] = collapse_no_add_p1; simpleCollapserTable[match][add] = collapse_no_add_p1; simpleCollapserTable[match][remove] = collapse_no_add_p1; simpleCollapserTable[match][match+modify] = collapse_no_add_p1; //tested simpleCollapserTable[match][match+add] = collapse_no_add_p1; simpleCollapserTable[match][match+remove] = collapse_no_add_p1; simpleCollapserTable[match][match+modify+add] = collapse_no_add_p1; simpleEvaluatorTable[add][empty] = Evaluator.TRUE; simpleEvaluatorTable[add][match] = no_rhs_reference; simpleEvaluatorTable[add][match+modify] = no_rhs_reference; simpleMapperTable[add][empty] = Mapper.EMPTY; simpleMapperTable[add][match] = mapper_add_p1; simpleMapperTable[add][match+modify] = mapper_add_p1; simpleCollapserTable[add][empty] = collapse_add_p1; simpleCollapserTable[add][match] = collapse_add_p1; simpleCollapserTable[add][match+modify] = collapse_add_p1; simpleEvaluatorTable[remove][empty] = Evaluator.TRUE; simpleEvaluatorTable[remove][remove] = Evaluator.TRUE; simpleMapperTable[remove][empty] = Mapper.EMPTY; simpleMapperTable[remove][remove] = Mapper.EMPTY; simpleCollapserTable[remove][empty] = collapse_no_add_p1; simpleCollapserTable[remove][remove] = collapse_no_add_p1; simpleEvaluatorTable[query][empty] = Evaluator.TRUE; simpleEvaluatorTable[query][add] = Evaluator.TRUE; simpleMapperTable[query][empty] = Mapper.EMPTY; simpleMapperTable[query][add] = Mapper.EMPTY; simpleCollapserTable[query][empty] = collapse_no_add_p1; simpleCollapserTable[query][add] = collapse_no_add_p1; simpleEvaluatorTable[match+modify][empty] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][match] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][add] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][remove] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][match+modify] = Evaluator.TRUE; //tested simpleEvaluatorTable[match+modify][match+add] = Evaluator.TRUE; //tested simpleEvaluatorTable[match+modify][match+remove] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][match+modify+add] = Evaluator.TRUE; simpleEvaluatorTable[match+modify][match+modify+remove] = Evaluator.TRUE; simpleMapperTable[match+modify][empty] = Mapper.EMPTY; simpleMapperTable[match+modify][match] = mapper_no_add_p1; simpleMapperTable[match+modify][add] = Mapper.EMPTY; simpleMapperTable[match+modify][remove] = Mapper.EMPTY; simpleMapperTable[match+modify][match+modify] = mapper_no_add_p1; //tested simpleMapperTable[match+modify][match+add] = mapper_no_add_p1; //tested simpleMapperTable[match+modify][match+remove] = mapper_no_add_p1; simpleMapperTable[match+modify][match+modify+add] = mapper_no_add_p1; simpleMapperTable[match+modify][match+modify+remove] = mapper_no_add_p1; simpleCollapserTable[match+modify][empty] = collapse_no_add_p1; simpleCollapserTable[match+modify][match] = collapse_no_add_p1; simpleCollapserTable[match+modify][add] = collapse_no_add_p1; simpleCollapserTable[match+modify][remove] = collapse_no_add_p1; simpleCollapserTable[match+modify][match+modify] = collapse_no_add_p1; //tested simpleCollapserTable[match+modify][match+add] = collapse_no_add_p1; //tested simpleCollapserTable[match+modify][match+remove] = collapse_no_add_p1; simpleCollapserTable[match+modify][match+modify+add] = collapse_no_add_p1; simpleCollapserTable[match+modify][match+modify+remove] = collapse_no_add_p1; simpleEvaluatorTable[match+add][empty] = Evaluator.TRUE; simpleEvaluatorTable[match+add][match] = no_rhs_reference; simpleEvaluatorTable[match+add][match+modify] = no_rhs_reference; //tested simpleMapperTable[match+add][empty] = Mapper.EMPTY; simpleMapperTable[match+add][match] = mapper_add_p1; simpleMapperTable[match+add][match+modify] = mapper_add_p1; //tested simpleCollapserTable[match+add][empty] = collapse_add_p1; simpleCollapserTable[match+add][match] = collapse_add_p1; simpleCollapserTable[match+add][match+modify] = collapse_add_p1; //tested simpleEvaluatorTable[match+remove][remove] = Evaluator.TRUE; simpleMapperTable[match+remove][remove] = Mapper.EMPTY; simpleCollapserTable[match+remove][remove] = collapse_no_add_p1; simpleEvaluatorTable[add+query][match] = no_rhs_reference; simpleEvaluatorTable[add+query][match+modify] = no_rhs_reference; simpleMapperTable[add+query][match] = mapper_add_p1; simpleMapperTable[add+query][match+modify] = mapper_add_p1; simpleCollapserTable[add+query][match] = collapse_add_p1; simpleCollapserTable[add+query][match+modify] = collapse_add_p1; simpleEvaluatorTable[match+modify+add][empty] = Evaluator.TRUE; simpleEvaluatorTable[match+modify+add][match] = no_rhs_reference; simpleEvaluatorTable[match+modify+add][match+modify] = no_rhs_reference; simpleMapperTable[match+modify+add][empty] = Mapper.EMPTY; simpleMapperTable[match+modify+add][match] = mapper_add_p1; simpleMapperTable[match+modify+add][match+modify] = mapper_add_p1; simpleCollapserTable[match+modify+add][empty] = collapse_add_p1; simpleCollapserTable[match+modify+add][match] = collapse_add_p1; simpleCollapserTable[match+modify+add][match+modify] = collapse_add_p1; simpleEvaluatorTable[match+modify+remove][remove] = Evaluator.TRUE; simpleMapperTable[match+modify+remove][remove] = Mapper.EMPTY; simpleCollapserTable[match+modify+remove][remove] = collapse_no_add_p1; //Now for "retrieval types" retrievalEvaluatorTable[empty][match] = Evaluator.TRUE; retrievalEvaluatorTable[empty][add] = Evaluator.TRUE; //tested retrievalEvaluatorTable[empty][query] = Evaluator.TRUE; retrievalEvaluatorTable[empty][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[empty][match+remove] = Evaluator.TRUE; retrievalEvaluatorTable[empty][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[empty][add+query] = Evaluator.TRUE; retrievalEvaluatorTable[empty][match+add+query] = Evaluator.TRUE; retrievalEvaluatorTable[empty][match+remove+query] = Evaluator.TRUE; retrievalMapperTable[empty][match] = Mapper.EMPTY; retrievalMapperTable[empty][add] = Mapper.EMPTY; //tested retrievalMapperTable[empty][query] = Mapper.EMPTY; retrievalMapperTable[empty][match+add] = Mapper.EMPTY; retrievalMapperTable[empty][match+remove] = Mapper.EMPTY; retrievalMapperTable[empty][match+query] = Mapper.EMPTY; retrievalMapperTable[empty][add+query] = Mapper.EMPTY; retrievalMapperTable[empty][match+add+query] = Mapper.EMPTY; retrievalMapperTable[empty][match+remove+query] = Mapper.EMPTY; retrievalCollapserTable[empty][match] = collapse_no_add_p1; retrievalCollapserTable[empty][add] = collapse_no_add_p1; //tested retrievalCollapserTable[empty][query] = collapse_no_add_p1; retrievalCollapserTable[empty][match+add] = collapse_no_add_p1; retrievalCollapserTable[empty][match+remove] = collapse_no_add_p1; retrievalCollapserTable[empty][match+query] = collapse_no_add_p1; retrievalCollapserTable[empty][add+query] = collapse_no_add_p1; retrievalCollapserTable[empty][match+add+query] = collapse_no_add_p1; retrievalCollapserTable[empty][match+remove+query] = collapse_no_add_p1; retrievalEvaluatorTable[match][empty] = Evaluator.TRUE; retrievalEvaluatorTable[match][match] = Evaluator.TRUE; retrievalEvaluatorTable[match][add] = Evaluator.TRUE; retrievalEvaluatorTable[match][query] = Evaluator.TRUE; retrievalEvaluatorTable[match][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[match][match+remove] = Evaluator.TRUE; retrievalEvaluatorTable[match][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[match][add+query] = Evaluator.TRUE; retrievalEvaluatorTable[match][match+add+query] = Evaluator.TRUE; retrievalEvaluatorTable[match][match+remove+query] = Evaluator.TRUE; retrievalMapperTable[match][empty] = Mapper.EMPTY; retrievalMapperTable[match][match] = mapper_no_add_p1; retrievalMapperTable[match][add] = Mapper.EMPTY; retrievalMapperTable[match][query] = Mapper.EMPTY; retrievalMapperTable[match][match+add] = mapper_no_add_p1; retrievalMapperTable[match][match+remove] = mapper_no_add_p1; retrievalMapperTable[match][match+query] = mapper_no_add_p1; retrievalMapperTable[match][add+query] = Mapper.EMPTY; retrievalMapperTable[match][match+add+query] = mapper_no_add_p1; retrievalMapperTable[match][match+remove+query] = mapper_no_add_p1; retrievalCollapserTable[match][empty] = collapse_no_add_p1; retrievalCollapserTable[match][match] = collapse_no_add_p1; retrievalCollapserTable[match][add] = collapse_no_add_p1; retrievalCollapserTable[match][query] = collapse_no_add_p1; retrievalCollapserTable[match][match+add] = collapse_no_add_p1; retrievalCollapserTable[match][match+remove] = collapse_no_add_p1; retrievalCollapserTable[match][match+query] = collapse_no_add_p1; retrievalCollapserTable[match][add+query] = collapse_no_add_p1; retrievalCollapserTable[match][match+add+query] = collapse_no_add_p1; retrievalCollapserTable[match][match+remove+query] = collapse_no_add_p1; retrievalEvaluatorTable[add][empty] = Evaluator.TRUE; retrievalEvaluatorTable[add][match] = Evaluator.TRUE; retrievalEvaluatorTable[add][add] = Evaluator.TRUE; retrievalEvaluatorTable[add][query] = p2_busy_or_empty; //not yet harvested; otherwise create a situation where the p2 fires once chunk in buffer, but when fire compiled production not in there. retrievalEvaluatorTable[add][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[add][match+remove] = Evaluator.TRUE; retrievalEvaluatorTable[add][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[add][add+query] = Evaluator.TRUE; //FIXME: not sure this is right, but ok for now... retrievalEvaluatorTable[add][remove+query] = Evaluator.TRUE; retrievalEvaluatorTable[add][match+add+query] = Evaluator.TRUE; retrievalEvaluatorTable[add][match+remove+query] = Evaluator.TRUE; //tested retrievalMapperTable[add][empty] = Mapper.EMPTY; retrievalMapperTable[add][match] = mapper_nondeterministic_add_p1; retrievalMapperTable[add][add] = Mapper.EMPTY; retrievalMapperTable[add][query] = Mapper.EMPTY; retrievalMapperTable[add][match+add] = mapper_nondeterministic_add_p1; retrievalMapperTable[add][match+remove] = mapper_nondeterministic_add_p1; retrievalMapperTable[add][match+query] = mapper_nondeterministic_add_p1; retrievalMapperTable[add][add+query] = Mapper.EMPTY; retrievalMapperTable[add][remove+query] = Mapper.EMPTY; retrievalMapperTable[add][match+add+query] = mapper_nondeterministic_add_p1; retrievalMapperTable[add][match+remove+query] = mapper_nondeterministic_add_p1; //tested retrievalCollapserTable[add][empty] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[add][match] = collapse_add_p1;//collapse_cancompileout_add_p1; -- this is wrong because at the end of this there is still a chunk in the buffer and compiling out compiles it out. retrievalCollapserTable[add][add] = collapse_compileout_add_p1; retrievalCollapserTable[add][query] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[add][match+add] = collapse_compileout_add_p1; retrievalCollapserTable[add][match+remove] = collapse_compileout_add_p1; retrievalCollapserTable[add][match+query] = collapse_add_p1; //collapse_cancompileout_add_p1; retrievalCollapserTable[add][add+query] = collapse_compileout_add_p1; retrievalCollapserTable[add][remove+query] = collapse_compileout_add_p1; retrievalCollapserTable[add][match+remove+query] = collapse_compileout_add_p1; //tested retrievalEvaluatorTable[query][empty] = Evaluator.TRUE; retrievalEvaluatorTable[query][match] = Evaluator.TRUE; retrievalEvaluatorTable[query][add] = Evaluator.TRUE; retrievalEvaluatorTable[query][query] = same_queries; retrievalEvaluatorTable[query][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[query][match+query] = same_queries; retrievalEvaluatorTable[query][add+query] = same_queries; retrievalEvaluatorTable[query][match+add+query] = same_queries; retrievalMapperTable[query][empty] = Mapper.EMPTY; retrievalMapperTable[query][match] = Mapper.EMPTY; retrievalMapperTable[query][add] = Mapper.EMPTY; retrievalMapperTable[query][query] = Mapper.EMPTY; retrievalMapperTable[query][match+add] = Mapper.EMPTY; retrievalMapperTable[query][match+query] = Mapper.EMPTY; retrievalMapperTable[query][add+query] = Mapper.EMPTY; retrievalMapperTable[query][match+add+query] = Mapper.EMPTY; retrievalCollapserTable[query][empty] = collapse_no_add_p1; retrievalCollapserTable[query][match] = collapse_no_add_p1; retrievalCollapserTable[query][add] = collapse_no_add_p1; retrievalCollapserTable[query][query] = collapse_no_add_p1; retrievalCollapserTable[query][match+add] = collapse_no_add_p1; retrievalCollapserTable[query][match+query] = collapse_no_add_p1; retrievalCollapserTable[query][add+query] = collapse_no_add_p1; retrievalCollapserTable[query][match+add+query] = collapse_no_add_p1; retrievalEvaluatorTable[match+add][empty] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][match] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][add] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][query] = p2_busy_or_empty; retrievalEvaluatorTable[match+add][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][match+remove] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[match+add][add+query] = p2_busy_or_empty; retrievalEvaluatorTable[match+add][match+add+query] = Evaluator.TRUE; retrievalMapperTable[match+add][empty] = Mapper.EMPTY; retrievalMapperTable[match+add][match] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add][add] = Mapper.EMPTY; retrievalMapperTable[match+add][query] = Mapper.EMPTY; retrievalMapperTable[match+add][match+add] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add][match+remove] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add][match+query] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add][add+query] = Mapper.EMPTY; retrievalMapperTable[match+add][match+add+query] = mapper_nondeterministic_add_p1; retrievalCollapserTable[match+add][empty] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[match+add][match] = collapse_add_p1; //don't use compile out version since at the end of the firing there is still a chunk in the retrieval buffer retrievalCollapserTable[match+add][add] = collapse_compileout_add_p1; retrievalCollapserTable[match+add][query] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[match+add][match+add] = collapse_compileout_add_p1; retrievalCollapserTable[match+add][match+remove] = collapse_compileout_add_p1; retrievalCollapserTable[match+add][match+query] = collapse_add_p1; retrievalCollapserTable[match+add][add+query] = collapse_compileout_add_p1; retrievalCollapserTable[match+add][match+add+query] = collapse_compileout_add_p1; retrievalEvaluatorTable[match+query][empty] = Evaluator.TRUE; retrievalEvaluatorTable[match+query][match] = Evaluator.TRUE; retrievalEvaluatorTable[match+query][add] = Evaluator.TRUE; retrievalEvaluatorTable[match+query][remove] = Evaluator.TRUE; retrievalEvaluatorTable[match+query][query] = same_queries; retrievalEvaluatorTable[match+query][match+query] = same_queries; retrievalEvaluatorTable[match+query][add+query] = same_queries; retrievalEvaluatorTable[match+query][remove+query] = same_queries; retrievalMapperTable[match+query][empty] = Mapper.EMPTY; retrievalMapperTable[match+query][match] = mapper_no_add_p1; retrievalMapperTable[match+query][add] = Mapper.EMPTY; retrievalMapperTable[match+query][remove] = Mapper.EMPTY; retrievalMapperTable[match+query][query] = Mapper.EMPTY; retrievalMapperTable[match+query][match+query] = mapper_no_add_p1; retrievalMapperTable[match+query][add+query] = Mapper.EMPTY; retrievalMapperTable[match+query][remove+query] = Mapper.EMPTY; retrievalCollapserTable[match+query][empty] = collapse_no_add_p1; retrievalCollapserTable[match+query][match] = collapse_no_add_p1; retrievalCollapserTable[match+query][add] = collapse_no_add_p1; retrievalCollapserTable[match+query][remove] = collapse_no_add_p1; retrievalCollapserTable[match+query][query] = collapse_no_add_p1; retrievalCollapserTable[match+query][match+query] = collapse_no_add_p1; retrievalCollapserTable[match+query][add+query] = collapse_no_add_p1; retrievalCollapserTable[match+query][remove+query] = collapse_no_add_p1; retrievalEvaluatorTable[add+query][empty] = Evaluator.TRUE; retrievalEvaluatorTable[add+query][match] = Evaluator.TRUE; retrievalEvaluatorTable[add+query][add] = Evaluator.TRUE; retrievalEvaluatorTable[add+query][query] = p2_busy_or_empty; retrievalEvaluatorTable[add+query][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[add+query][match+remove] = Evaluator.TRUE; //tested retrievalEvaluatorTable[add+query][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[add+query][add+query] = p2_busy_or_empty; retrievalEvaluatorTable[add+query][match+add+query] = Evaluator.TRUE; //tested retrievalEvaluatorTable[add+query][match+remove+query] = Evaluator.TRUE; //tested retrievalMapperTable[add+query][empty] = Mapper.EMPTY; retrievalMapperTable[add+query][match] = mapper_nondeterministic_add_p1; retrievalMapperTable[add+query][add] = Mapper.EMPTY; retrievalMapperTable[add+query][query] = Mapper.EMPTY; retrievalMapperTable[add+query][match+add] = mapper_nondeterministic_add_p1; retrievalMapperTable[add+query][match+remove] = mapper_nondeterministic_add_p1; //tested retrievalMapperTable[add+query][match+query] = mapper_nondeterministic_add_p1; retrievalMapperTable[add+query][add+query] = Mapper.EMPTY; retrievalMapperTable[add+query][match+add+query] = mapper_nondeterministic_add_p1; //tested retrievalMapperTable[add+query][match+remove+query] = mapper_nondeterministic_add_p1; //tested retrievalCollapserTable[add+query][empty] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[add+query][match] = collapse_add_p1; retrievalCollapserTable[add+query][add] = collapse_compileout_add_p1; retrievalCollapserTable[add+query][query] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[add+query][match+add] = collapse_compileout_add_p1; retrievalCollapserTable[add+query][match+remove] = collapse_compileout_add_p1; //tested //remove just lets us pretend that there is strict harvesting, even if there is not retrievalCollapserTable[add+query][match+query] = collapse_add_p1; retrievalCollapserTable[add+query][add+query] = collapse_compileout_add_p1; retrievalCollapserTable[add+query][match+add+query] = collapse_compileout_add_p1; //tested retrievalCollapserTable[add+query][match+remove+query] = collapse_compileout_add_p1; //tested retrievalEvaluatorTable[match+add+query][empty] = Evaluator.TRUE; retrievalEvaluatorTable[match+add+query][match] = Evaluator.TRUE; retrievalEvaluatorTable[match+add+query][add] = Evaluator.TRUE; retrievalEvaluatorTable[match+add+query][query] = p2_busy_or_empty; retrievalEvaluatorTable[match+add+query][match+add] = Evaluator.TRUE; retrievalEvaluatorTable[match+add+query][match+remove] = Evaluator.TRUE; //tested retrievalEvaluatorTable[match+add+query][match+query] = Evaluator.TRUE; retrievalEvaluatorTable[match+add+query][add+query] = p2_busy_or_empty; retrievalEvaluatorTable[match+add+query][match+add+query] = Evaluator.TRUE; retrievalMapperTable[match+add+query][empty] = Mapper.EMPTY; retrievalMapperTable[match+add+query][match] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add+query][add] = Mapper.EMPTY; retrievalMapperTable[match+add+query][query] = Mapper.EMPTY; retrievalMapperTable[match+add+query][match+add] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add+query][match+remove] = mapper_nondeterministic_add_p1; //tested retrievalMapperTable[match+add+query][match+query] = mapper_nondeterministic_add_p1; retrievalMapperTable[match+add+query][add+query] = Mapper.EMPTY; retrievalMapperTable[match+add+query][match+add+query] = mapper_nondeterministic_add_p1; retrievalCollapserTable[match+add+query][empty] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[match+add+query][match] = collapse_add_p1; retrievalCollapserTable[match+add+query][add] = collapse_compileout_add_p1; retrievalCollapserTable[match+add+query][query] = collapse_nonimmediate_add_p1_not_harvested; retrievalCollapserTable[match+add+query][match+add] = collapse_compileout_add_p1; retrievalCollapserTable[match+add+query][match+remove] = collapse_compileout_add_p1; //tested retrievalCollapserTable[match+add+query][match+query] = collapse_add_p1; retrievalCollapserTable[match+add+query][add+query] = collapse_compileout_add_p1; retrievalCollapserTable[match+add+query][match+add+query] = collapse_compileout_add_p1; retrievalEvaluatorTable[match+remove+query][empty] = Evaluator.TRUE; //tested retrievalMapperTable[match+remove+query][empty] = Mapper.EMPTY; //tested retrievalCollapserTable[match+remove+query][empty] = collapse_no_add_p1; //tested //Now for perceptual ones. perceptualEvaluatorTable[empty][match] = Evaluator.TRUE; perceptualEvaluatorTable[empty][add] = Evaluator.TRUE; perceptualEvaluatorTable[empty][query] = Evaluator.TRUE; perceptualEvaluatorTable[empty][match+add] = Evaluator.TRUE; perceptualEvaluatorTable[empty][match+remove] = Evaluator.TRUE; perceptualEvaluatorTable[empty][match+query] = Evaluator.TRUE; perceptualEvaluatorTable[empty][add+query] = Evaluator.TRUE; perceptualEvaluatorTable[empty][match+add+query] = Evaluator.TRUE; perceptualEvaluatorTable[empty][match+remove+query] = Evaluator.TRUE; perceptualMapperTable[empty][match] = Mapper.EMPTY; perceptualMapperTable[empty][add] = Mapper.EMPTY; perceptualMapperTable[empty][query] = Mapper.EMPTY; perceptualMapperTable[empty][match+add] = Mapper.EMPTY; perceptualMapperTable[empty][match+remove] = Mapper.EMPTY; perceptualMapperTable[empty][match+query] = Mapper.EMPTY; perceptualMapperTable[empty][add+query] = Mapper.EMPTY; perceptualMapperTable[empty][match+add+query] = Mapper.EMPTY; perceptualMapperTable[empty][match+remove+query] = Mapper.EMPTY; perceptualCollapserTable[empty][match] = collapse_no_add_p1; perceptualCollapserTable[empty][add] = collapse_no_add_p1; perceptualCollapserTable[empty][query] = collapse_no_add_p1; perceptualCollapserTable[empty][match+add] = collapse_no_add_p1; perceptualCollapserTable[empty][match+remove] = collapse_no_add_p1; perceptualCollapserTable[empty][match+query] = collapse_no_add_p1; perceptualCollapserTable[empty][add+query] = collapse_no_add_p1; perceptualCollapserTable[empty][match+add+query] = collapse_no_add_p1; perceptualCollapserTable[empty][match+remove+query] = collapse_no_add_p1; perceptualEvaluatorTable[add][empty] = Evaluator.TRUE; perceptualEvaluatorTable[add][query] = p2_busy_or_empty; perceptualMapperTable[add][empty] = Mapper.EMPTY; perceptualMapperTable[add][query] = Mapper.EMPTY; perceptualCollapserTable[add][empty] = collapse_nonimmediate_add_p1_not_harvested; perceptualCollapserTable[add][query] = collapse_nonimmediate_add_p1_not_harvested; perceptualEvaluatorTable[match][empty] = Evaluator.TRUE; //perceptualEvaluatorTable[match][add] = Evaluator.TRUE; -- is this buffer stuffing...? perceptualEvaluatorTable[match][query] = Evaluator.TRUE; //perceptualEvaluatorTable[match][match+add] = Evaluator.TRUE; perceptualEvaluatorTable[match][match+remove] = Evaluator.TRUE; perceptualEvaluatorTable[match][match+query] = Evaluator.TRUE; //perceptualEvaluatorTable[match][add+query] = Evaluator.TRUE; //perceptualEvaluatorTable[match][match+add+query] = Evaluator.TRUE; perceptualEvaluatorTable[match][match+remove+query] = Evaluator.TRUE; perceptualMapperTable[match][empty] = Mapper.EMPTY; perceptualMapperTable[match][query] = Mapper.EMPTY; perceptualMapperTable[match][match+remove] = mapper_no_add_p1; perceptualMapperTable[match][match+query] = mapper_no_add_p1; perceptualMapperTable[match][match+remove+query] = mapper_no_add_p1; perceptualCollapserTable[match][empty] = collapse_no_add_p1; perceptualCollapserTable[match][query] = collapse_no_add_p1; perceptualCollapserTable[match][match+remove] = collapse_no_add_p1; perceptualCollapserTable[match][match+query] = collapse_no_add_p1; perceptualCollapserTable[match][match+remove+query] = collapse_no_add_p1; perceptualEvaluatorTable[query][empty] = Evaluator.TRUE; perceptualEvaluatorTable[query][match] = Evaluator.TRUE; perceptualEvaluatorTable[query][add] = Evaluator.TRUE; perceptualEvaluatorTable[query][query] = same_queries; perceptualEvaluatorTable[query][match+add] = Evaluator.TRUE; perceptualEvaluatorTable[query][match+remove] = Evaluator.TRUE; perceptualEvaluatorTable[query][match+query] = same_queries; perceptualEvaluatorTable[query][add+query] = same_queries; perceptualEvaluatorTable[query][match+add+query] = same_queries; perceptualEvaluatorTable[query][match+remove+query] = same_queries; perceptualMapperTable[query][empty] = Mapper.EMPTY; perceptualMapperTable[query][match] = Mapper.EMPTY; perceptualMapperTable[query][add] = Mapper.EMPTY; perceptualMapperTable[query][query] = Mapper.EMPTY; perceptualMapperTable[query][match+add] = Mapper.EMPTY; perceptualMapperTable[query][match+remove] = Mapper.EMPTY; perceptualMapperTable[query][match+query] = Mapper.EMPTY; perceptualMapperTable[query][add+query] = Mapper.EMPTY; perceptualMapperTable[query][match+add+query] = Mapper.EMPTY; perceptualMapperTable[query][match+remove+query] = Mapper.EMPTY; perceptualCollapserTable[query][empty] = collapse_no_add_p1; perceptualCollapserTable[query][match] = collapse_no_add_p1; perceptualCollapserTable[query][add] = collapse_no_add_p1; perceptualCollapserTable[query][query] = collapse_no_add_p1; perceptualCollapserTable[query][match+add] = collapse_no_add_p1; perceptualCollapserTable[query][match+remove] = collapse_no_add_p1; perceptualCollapserTable[query][match+query] = collapse_no_add_p1; perceptualCollapserTable[query][add+query] = collapse_no_add_p1; perceptualCollapserTable[query][match+add+query] = collapse_no_add_p1; perceptualCollapserTable[query][match+remove+query] = collapse_no_add_p1; perceptualEvaluatorTable[match+add][empty] = Evaluator.TRUE; perceptualEvaluatorTable[match+add][query] = p2_busy_or_empty; perceptualMapperTable[match+add][empty] = Mapper.EMPTY; perceptualMapperTable[match+add][query] = Mapper.EMPTY; perceptualCollapserTable[match+add][empty] = collapse_nonimmediate_add_p1_not_harvested; perceptualCollapserTable[match+add][query] = collapse_nonimmediate_add_p1_not_harvested; perceptualEvaluatorTable[match+remove][empty] = Evaluator.TRUE; perceptualEvaluatorTable[match+remove][add] = Evaluator.TRUE; perceptualEvaluatorTable[match+remove][query] = Evaluator.TRUE; perceptualEvaluatorTable[match+remove][add+query] = Evaluator.TRUE; perceptualMapperTable[match+remove][empty] = Mapper.EMPTY; perceptualMapperTable[match+remove][add] = Mapper.EMPTY; perceptualMapperTable[match+remove][query] = Mapper.EMPTY; perceptualMapperTable[match+remove][add+query] = Mapper.EMPTY; perceptualCollapserTable[match+remove][empty] = collapse_no_add_p1; perceptualCollapserTable[match+remove][add] = collapse_no_add_p1; perceptualCollapserTable[match+remove][query] = collapse_no_add_p1; perceptualCollapserTable[match+remove][add+query] = collapse_no_add_p1; perceptualEvaluatorTable[match+query][empty] = Evaluator.TRUE; //perceptualEvaluatorTable[match+query][add] = Evaluator.TRUE; buffer stuffing?? perceptualEvaluatorTable[match+query][query] = same_queries; //perceptualEvaluatorTable[match+query][match+add] = Evaluator.TRUE; perceptualEvaluatorTable[match+query][match+remove] = Evaluator.TRUE; perceptualEvaluatorTable[match+query][match+query] = Evaluator.TRUE; //perceptualEvaluatorTable[match+query][add+query] = same_queries; //perceptualEvaluatorTable[match+query][match+add+query] = Evaluator.TRUE; perceptualEvaluatorTable[match+query][match+remove+query] = Evaluator.TRUE; perceptualMapperTable[match+query][empty] = Mapper.EMPTY; perceptualMapperTable[match+query][query] = Mapper.EMPTY; perceptualMapperTable[match+query][match+remove] = mapper_no_add_p1; perceptualMapperTable[match+query][match+query] = mapper_no_add_p1; perceptualMapperTable[match+query][match+remove+query] = mapper_no_add_p1; perceptualCollapserTable[match+query][empty] = collapse_no_add_p1; perceptualCollapserTable[match+query][query] = collapse_no_add_p1; perceptualCollapserTable[match+query][match+remove] = collapse_no_add_p1; perceptualCollapserTable[match+query][match+query] = collapse_no_add_p1; perceptualCollapserTable[match+query][match+remove+query] = collapse_no_add_p1; perceptualEvaluatorTable[add+query][empty] = Evaluator.TRUE; perceptualEvaluatorTable[add+query][query] = p2_busy_or_empty; perceptualMapperTable[add+query][empty] = Mapper.EMPTY; perceptualMapperTable[add+query][query] = Mapper.EMPTY; perceptualCollapserTable[add+query][empty] = collapse_nonimmediate_add_p1_not_harvested; perceptualCollapserTable[add+query][query] = collapse_nonimmediate_add_p1_not_harvested; perceptualEvaluatorTable[match+add+query][empty] = Evaluator.TRUE; perceptualEvaluatorTable[match+add+query][query] = p2_busy_or_empty; perceptualMapperTable[match+add+query][empty] = Mapper.EMPTY; perceptualMapperTable[match+add+query][query] = Mapper.EMPTY; perceptualCollapserTable[match+add+query][empty] = collapse_nonimmediate_add_p1_not_harvested; perceptualCollapserTable[match+add+query][query] = collapse_nonimmediate_add_p1_not_harvested; perceptualEvaluatorTable[match+remove+query][empty] = Evaluator.TRUE; perceptualEvaluatorTable[match+remove+query][add] = Evaluator.TRUE; perceptualEvaluatorTable[match+remove+query][query] = same_queries; perceptualEvaluatorTable[match+remove+query][add+query] = same_queries; perceptualMapperTable[match+remove+query][empty] = Mapper.EMPTY; perceptualMapperTable[match+remove+query][add] = Mapper.EMPTY; perceptualMapperTable[match+remove+query][query] = Mapper.EMPTY; perceptualMapperTable[match+remove+query][add+query] = Mapper.EMPTY; perceptualCollapserTable[match+remove+query][empty] = collapse_no_add_p1; perceptualCollapserTable[match+remove+query][add] = collapse_no_add_p1; perceptualCollapserTable[match+remove+query][query] = collapse_no_add_p1; perceptualCollapserTable[match+remove+query][add+query] = collapse_no_add_p1; } }