1 package org.simantics.scl.compiler.elaboration.chr.planning.items;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
5 import org.simantics.scl.compiler.elaboration.chr.CHRRelation;
6 import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;
7 import org.simantics.scl.compiler.elaboration.chr.plan.IterateConstraintOp;
8 import org.simantics.scl.compiler.elaboration.chr.plan.IterateRelationOp;
9 import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;
10 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
11 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
12 import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
13 import org.simantics.scl.compiler.elaboration.expressions.EApply;
14 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
15 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
16 import org.simantics.scl.compiler.elaboration.expressions.Expression;
17 import org.simantics.scl.compiler.elaboration.expressions.Variable;
18 import org.simantics.scl.compiler.elaboration.java.Builtins;
19 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
21 import gnu.trove.set.hash.THashSet;
22 import gnu.trove.set.hash.TIntHashSet;
24 public class GenericPrePlanItem extends PrePlanItem {
25 public CHRLiteral literal;
26 public CHRRelation relation;
27 public Expression[] expressions;
28 public TIntHashSet[] variableSets;
31 public GenericPrePlanItem(CHRLiteral literal, CHRRelation relation, Expression[] expressions,
32 TIntHashSet[] variableSets, int secondaryPriority) {
33 super(secondaryPriority);
34 this.literal = literal;
35 this.relation = relation;
36 this.expressions = expressions;
37 this.variableSets = variableSets;
38 allVars = new TIntHashSet();
39 for(TIntHashSet variableSet : variableSets)
40 allVars.addAll(variableSet);
41 updatePrimaryPriority();
44 private void updatePrimaryPriority() {
47 for(int i=0;i<variableSets.length;++i)
48 if(variableSets[i].isEmpty()) {
52 if(boundCount == variableSets.length)
55 if(relation instanceof ExternalCHRRelation) {
56 SCLRelation sclRelation = ((ExternalCHRRelation)relation).relation;
57 double selectivity = sclRelation.getSelectivity(boundMask);
58 if(selectivity == Double.POSITIVE_INFINITY)
59 primaryPriority = Double.POSITIVE_INFINITY;
60 else if(selectivity < 1.0)
61 primaryPriority = 0.0;
62 else if(selectivity == 1.0)
63 primaryPriority = 1.0;
65 primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;
68 primaryPriority = 3.0 - ((double)boundCount) / variableSets.length;
73 public void initializeListeners(QueryPlanningContext context) {
74 context.listen(allVars, this);
78 public void variableSolved(QueryPlanningContext context, int variableId) {
79 for(TIntHashSet variableSet : variableSets)
80 variableSet.remove(variableId);
81 allVars.remove(variableId);
82 updatePrimaryPriority();
83 context.priorityQueue.adjust(this);
87 public void generate(QueryPlanningContext context) {
89 Expression[] boundExpressions = new Expression[expressions.length];
90 Variable[] freeVariables = new Variable[expressions.length];
91 int freeVariableCount = 0;
92 for(int i=0;i<expressions.length;++i)
93 if(variableSets[i].isEmpty()) {
94 boundExpressions[i] = expressions[i];
98 freeVariables[i] = ((EVariable)expressions[i]).getVariable();
101 if(relation instanceof CHRConstraint)
102 context.addPlanOp(new IterateConstraintOp(location, (CHRConstraint)relation, freeVariables, boundExpressions, boundMask,
103 killAfterMatch(), literal.passive));
104 else if(relation instanceof ExternalCHRRelation)
105 context.addPlanOp(new IterateRelationOp(location, ((ExternalCHRRelation)relation).relation,
106 freeVariables, boundExpressions, boundMask));
108 throw new InternalCompilerError();
109 if(freeVariableCount > 1) {
110 THashSet<Variable> usedVariables = new THashSet<Variable>(freeVariableCount);
111 for(int i=0;i<freeVariables.length;++i) {
112 Variable variable = freeVariables[i];
115 if(!usedVariables.add(variable)) {
116 Variable auxiliary = new Variable(variable.getName(), variable.getType());
117 freeVariables[i] = auxiliary;
118 context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, variable.getType()), new EVariable(auxiliary), new EVariable(variable))));
122 context.bind(allVars);
125 private boolean killAfterMatch() {
126 return literal.killAfterMatch && relation instanceof CHRConstraint;