package org.simantics.scl.compiler.elaboration.chr.planning.items; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Names; import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp; import org.simantics.scl.compiler.elaboration.chr.plan.IterateListOp; import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem; import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import gnu.trove.set.hash.TIntHashSet; public class MemberPrePlanItem extends PrePlanItem { public Expression expression1, expression2; public TIntHashSet variableSet1, variableSet2; public MemberPrePlanItem(Expression expression1, Expression expression2, TIntHashSet variableSet1, TIntHashSet variableSet2, int secondaryPriority) { super(secondaryPriority); this.expression1 = expression1; this.expression2 = expression2; this.variableSet1 = variableSet1; this.variableSet2 = variableSet2; updatePrimaryPriority(); } private void updatePrimaryPriority() { if(variableSet2.isEmpty()) { if(variableSet1.isEmpty()) primaryPriority = 0; else primaryPriority = 2.0; } } @Override public void initializeListeners(QueryPlanningContext context) { context.listen(variableSet1, this); context.listen(variableSet2, this); } @Override public void variableSolved(QueryPlanningContext context, int variableId) { variableSet1.remove(variableId); variableSet2.remove(variableId); updatePrimaryPriority(); context.priorityQueue.adjust(this); } @Override public void generate(QueryPlanningContext context) { if(!variableSet2.isEmpty()) throw new InternalCompilerError("Unsolvable query."); if(variableSet1.isEmpty()) context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(context.getCompilationContext().getValue(Names.Prelude_elem)), expression1, expression2))); else context.addPlanOp(new IterateListOp(location, ((EVariable)expression1).getVariable(), expression2)); context.bind(variableSet1); } }