package org.simantics.scl.compiler.elaboration.chr.planning; import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; import org.simantics.scl.compiler.elaboration.chr.plan.AccessFactOp; import org.simantics.scl.compiler.elaboration.chr.plan.ClaimOp; import org.simantics.scl.compiler.elaboration.chr.plan.ExecuteOp; import org.simantics.scl.compiler.elaboration.chr.plan.MatchOp; import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp; import org.simantics.scl.compiler.elaboration.chr.planning.items.CheckPrePlanItem; import org.simantics.scl.compiler.elaboration.chr.planning.items.EqualsPrePlanItem; import org.simantics.scl.compiler.elaboration.chr.planning.items.GenericPrePlanItem; import org.simantics.scl.compiler.elaboration.chr.planning.items.MemberPrePlanItem; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; import org.simantics.scl.compiler.elaboration.expressions.EApplyType; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.errors.Locations; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.TIntHashSet; public class QueryPlanningContext { CompilationContext compilationContext; public PlanPriorityQueue priorityQueue = new PlanPriorityQueue(); ArrayList variables; TObjectIntHashMap variableMap; ArrayList> itemsContainingVariable; ArrayList planOps = new ArrayList(); public QueryPlanningContext(CompilationContext compilationContext, Variable[] variables) { this.compilationContext = compilationContext; this.variables = new ArrayList(variables.length*2); this.variableMap = new TObjectIntHashMap(variables.length, Constants.DEFAULT_LOAD_FACTOR, -1); itemsContainingVariable = new ArrayList>(variables.length*2); for(Variable variable : variables) addVariable(variable); } private void addVariable(Variable variable) { int id = variables.size(); variables.add(variable); variableMap.put(variable, id); itemsContainingVariable.add(new ArrayList(2)); } public void add(CHRLiteral literal, int secondaryPriority) { if(literal.relation instanceof SpecialCHRRelation) { switch((SpecialCHRRelation)literal.relation) { case CHECK: addCheck(literal.location, literal.parameters[0], secondaryPriority); return; case EQUALS: addGenericEquals(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority); return; case MEMBER: addMember(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority); return; case ASSIGN: throw new InternalCompilerError(literal.location, "ASSIGN constraint is not allowed in query compilation."); case EXECUTE: throw new InternalCompilerError(literal.location, "EXECUTE constraint is not allowed in query compilation."); } } addGenericConstraint(literal, secondaryPriority); } private TIntHashSet getVars(Expression expression, int initialCapacity) { TIntHashSet variableSet = new TIntHashSet(initialCapacity); expression.collectVars(variableMap, variableSet); return variableSet; } private TIntHashSet[] getVars(Expression[] expressions, int initialCapacity) { TIntHashSet[] variableSets = new TIntHashSet[expressions.length]; for(int i=0;i getPlanOps() { return planOps; } private final TIntProcedure BIND_PROCEDURE = new TIntProcedure() { @Override public boolean execute(int variableId) { ArrayList l = itemsContainingVariable.get(variableId); for(PrePlanItem item : l) item.variableSolved(QueryPlanningContext.this, variableId); l.clear(); return true; } }; public void bind(TIntHashSet variableSet) { variableSet.forEach(BIND_PROCEDURE); } public void addPlanOp(PlanOp planOp) { planOps.add(planOp); } public CompilationContext getCompilationContext() { return compilationContext; } public void activate(CHRLiteral literal, Expression inputFact, int secondaryPriority) { Variable[] variables = new Variable[literal.parameters.length]; for(int i=0;i