-package org.simantics.scl.compiler.elaboration.chr.planning.items;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;\r
-import org.simantics.scl.compiler.elaboration.chr.CHRRelation;\r
-import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;\r
-import org.simantics.scl.compiler.elaboration.chr.plan.IterateConstraintOp;\r
-import org.simantics.scl.compiler.elaboration.chr.plan.IterateRelationOp;\r
-import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;\r
-import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;\r
-import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
-import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
-import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
-import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
-import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
-import org.simantics.scl.compiler.elaboration.java.Builtins;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class GenericPrePlanItem extends PrePlanItem {\r
- public CHRLiteral literal;\r
- public CHRRelation relation;\r
- public Expression[] expressions;\r
- public TIntHashSet[] variableSets;\r
- TIntHashSet allVars;\r
-\r
- public GenericPrePlanItem(CHRLiteral literal, CHRRelation relation, Expression[] expressions,\r
- TIntHashSet[] variableSets, int secondaryPriority) {\r
- super(secondaryPriority);\r
- this.literal = literal;\r
- this.relation = relation;\r
- this.expressions = expressions;\r
- this.variableSets = variableSets;\r
- allVars = new TIntHashSet();\r
- for(TIntHashSet variableSet : variableSets)\r
- allVars.addAll(variableSet);\r
- updatePrimaryPriority();\r
- }\r
-\r
- private void updatePrimaryPriority() {\r
- int boundCount = 0;\r
- int boundMask = 0;\r
- for(int i=0;i<variableSets.length;++i)\r
- if(variableSets[i].isEmpty()) {\r
- ++boundCount;\r
- boundMask |= 1 << i;\r
- }\r
- if(boundCount == variableSets.length)\r
- primaryPriority = 0;\r
- else {\r
- if(relation instanceof ExternalCHRRelation) {\r
- SCLRelation sclRelation = ((ExternalCHRRelation)relation).relation;\r
- double selectivity = sclRelation.getSelectivity(boundMask);\r
- if(selectivity == Double.POSITIVE_INFINITY)\r
- primaryPriority = Double.POSITIVE_INFINITY;\r
- else if(selectivity < 1.0)\r
- primaryPriority = 0.0;\r
- else if(selectivity == 1.0)\r
- primaryPriority = 1.0;\r
- else\r
- primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;\r
- }\r
- else\r
- primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;\r
- }\r
- }\r
-\r
- @Override\r
- public void initializeListeners(QueryPlanningContext context) {\r
- context.listen(allVars, this);\r
- }\r
-\r
- @Override\r
- public void variableSolved(QueryPlanningContext context, int variableId) {\r
- for(TIntHashSet variableSet : variableSets)\r
- variableSet.remove(variableId);\r
- allVars.remove(variableId);\r
- updatePrimaryPriority();\r
- context.priorityQueue.adjust(this);\r
- }\r
- \r
- @Override\r
- public void generate(QueryPlanningContext context) {\r
- int boundMask = 0;\r
- Expression[] boundExpressions = new Expression[expressions.length];\r
- Variable[] freeVariables = new Variable[expressions.length];\r
- int freeVariableCount = 0;\r
- for(int i=0;i<expressions.length;++i)\r
- if(variableSets[i].isEmpty()) {\r
- boundExpressions[i] = expressions[i];\r
- boundMask |= 1 << i;\r
- }\r
- else {\r
- freeVariables[i] = ((EVariable)expressions[i]).getVariable();\r
- ++freeVariableCount;\r
- }\r
- if(relation instanceof CHRConstraint)\r
- context.addPlanOp(new IterateConstraintOp(location, (CHRConstraint)relation, freeVariables, boundExpressions, boundMask,\r
- killAfterMatch(), literal.passive));\r
- else if(relation instanceof ExternalCHRRelation)\r
- context.addPlanOp(new IterateRelationOp(location, ((ExternalCHRRelation)relation).relation,\r
- freeVariables, boundExpressions, boundMask));\r
- else\r
- throw new InternalCompilerError();\r
- if(freeVariableCount > 1) {\r
- THashSet<Variable> usedVariables = new THashSet<Variable>(freeVariableCount);\r
- for(int i=0;i<freeVariables.length;++i) {\r
- Variable variable = freeVariables[i];\r
- if(variable == null)\r
- continue;\r
- if(!usedVariables.add(variable)) {\r
- Variable auxiliary = new Variable(variable.getName(), variable.getType());\r
- freeVariables[i] = auxiliary;\r
- context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, variable.getType()), new EVariable(auxiliary), new EVariable(variable))));\r
- }\r
- }\r
- }\r
- context.bind(allVars);\r
- }\r
-\r
- private boolean killAfterMatch() {\r
- return literal.killAfterMatch && relation instanceof CHRConstraint;\r
- }\r
-}\r
+package org.simantics.scl.compiler.elaboration.chr.planning.items;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
+import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;
+import org.simantics.scl.compiler.elaboration.chr.plan.IterateConstraintOp;
+import org.simantics.scl.compiler.elaboration.chr.plan.IterateRelationOp;
+import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
+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 org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.java.Builtins;
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class GenericPrePlanItem extends PrePlanItem {
+ public CHRLiteral literal;
+ public CHRRelation relation;
+ public Expression[] expressions;
+ public TIntHashSet[] variableSets;
+ TIntHashSet allVars;
+
+ public GenericPrePlanItem(CHRLiteral literal, CHRRelation relation, Expression[] expressions,
+ TIntHashSet[] variableSets, int secondaryPriority) {
+ super(secondaryPriority);
+ this.literal = literal;
+ this.relation = relation;
+ this.expressions = expressions;
+ this.variableSets = variableSets;
+ allVars = new TIntHashSet();
+ for(TIntHashSet variableSet : variableSets)
+ allVars.addAll(variableSet);
+ updatePrimaryPriority();
+ }
+
+ private void updatePrimaryPriority() {
+ int boundCount = 0;
+ int boundMask = 0;
+ for(int i=0;i<variableSets.length;++i)
+ if(variableSets[i].isEmpty()) {
+ ++boundCount;
+ boundMask |= 1 << i;
+ }
+ if(boundCount == variableSets.length)
+ primaryPriority = 0;
+ else {
+ if(relation instanceof ExternalCHRRelation) {
+ SCLRelation sclRelation = ((ExternalCHRRelation)relation).relation;
+ double selectivity = sclRelation.getSelectivity(boundMask);
+ if(selectivity == Double.POSITIVE_INFINITY)
+ primaryPriority = Double.POSITIVE_INFINITY;
+ else if(selectivity < 1.0)
+ primaryPriority = 0.0;
+ else if(selectivity == 1.0)
+ primaryPriority = 1.0;
+ else
+ primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;
+ }
+ else
+ primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;
+ }
+ }
+
+ @Override
+ public void initializeListeners(QueryPlanningContext context) {
+ context.listen(allVars, this);
+ }
+
+ @Override
+ public void variableSolved(QueryPlanningContext context, int variableId) {
+ for(TIntHashSet variableSet : variableSets)
+ variableSet.remove(variableId);
+ allVars.remove(variableId);
+ updatePrimaryPriority();
+ context.priorityQueue.adjust(this);
+ }
+
+ @Override
+ public void generate(QueryPlanningContext context) {
+ int boundMask = 0;
+ Expression[] boundExpressions = new Expression[expressions.length];
+ Variable[] freeVariables = new Variable[expressions.length];
+ int freeVariableCount = 0;
+ for(int i=0;i<expressions.length;++i)
+ if(variableSets[i].isEmpty()) {
+ boundExpressions[i] = expressions[i];
+ boundMask |= 1 << i;
+ }
+ else {
+ freeVariables[i] = ((EVariable)expressions[i]).getVariable();
+ ++freeVariableCount;
+ }
+ if(relation instanceof CHRConstraint)
+ context.addPlanOp(new IterateConstraintOp(location, (CHRConstraint)relation, freeVariables, boundExpressions, boundMask,
+ killAfterMatch(), literal.passive));
+ else if(relation instanceof ExternalCHRRelation)
+ context.addPlanOp(new IterateRelationOp(location, ((ExternalCHRRelation)relation).relation,
+ freeVariables, boundExpressions, literal.typeConstraintEvidenceParameters, boundMask));
+ else
+ throw new InternalCompilerError();
+ if(freeVariableCount > 1) {
+ THashSet<Variable> usedVariables = new THashSet<Variable>(freeVariableCount);
+ for(int i=0;i<freeVariables.length;++i) {
+ Variable variable = freeVariables[i];
+ if(variable == null)
+ continue;
+ if(!usedVariables.add(variable)) {
+ Variable auxiliary = new Variable(variable.getName(), variable.getType());
+ freeVariables[i] = auxiliary;
+ context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, variable.getType()), new EVariable(auxiliary), new EVariable(variable))));
+ }
+ }
+ }
+ context.bind(allVars);
+ }
+
+ private boolean killAfterMatch() {
+ return literal.killAfterMatch && relation instanceof CHRConstraint;
+ }
+}