-package org.simantics.scl.compiler.elaboration.chr;\r
-\r
-import org.simantics.scl.compiler.compilation.CompilationContext;\r
-import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;\r
-import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan;\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.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
-import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
-import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.parsing.Symbol;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class CHRRule extends Symbol {\r
- public int priority;\r
- public CHRQuery head;\r
- public CHRQuery body;\r
- public Variable[] existentialVariables;\r
- \r
- // Analysis\r
- public int firstPriorityExecuted;\r
- public int lastPriorityExecuted;\r
- \r
- public CHRRule(long location, CHRQuery head, CHRQuery body, Variable[] existentialVariables) {\r
- this.location = location;\r
- this.head = head;\r
- this.body = body;\r
- this.existentialVariables = existentialVariables;\r
- }\r
-\r
- public void resolve(TranslationContext context) {\r
- context.pushExistentialFrame();\r
- head.resolve(context);\r
- body.resolve(context);\r
- existentialVariables = context.popExistentialFrame();\r
- }\r
-\r
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
- head.collectRefs(allRefs, refs);\r
- body.collectRefs(allRefs, refs);\r
- }\r
-\r
- public void checkType(TypingContext context) {\r
- for(Variable variable : existentialVariables)\r
- variable.setType(Types.metaVar(Kinds.STAR));\r
- head.checkType(context);\r
- body.checkType(context);\r
- }\r
- \r
- public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
- head.collectVars(allVars, vars);\r
- body.collectVars(allVars, vars);\r
- }\r
-\r
- public void forVariables(VariableProcedure procedure) {\r
- head.forVariables(procedure);\r
- body.forVariables(procedure);\r
- }\r
-\r
- public void collectFreeVariables(THashSet<Variable> vars) {\r
- head.collectFreeVariables(vars);\r
- body.collectFreeVariables(vars);\r
- }\r
-\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- this.location = loc;\r
- head.setLocationDeep(loc);\r
- body.setLocationDeep(loc);\r
- }\r
- }\r
- \r
- public void simplify(SimplificationContext context) {\r
- head.simplify(context);\r
- body.simplify(context);\r
- }\r
-\r
- public void compile(CompilationContext compilationContext, CHRConstraint initConstraint) {\r
- boolean hasActiveLiteral = false;\r
- for(int i=0;i<head.literals.length;++i) {\r
- CHRLiteral literal = head.literals[i];\r
- if(literal.passive)\r
- continue;\r
- CHRConstraint constraint = (CHRConstraint)literal.relation;\r
- \r
- Variable activeFact = new Variable("activeFact", constraint.factType);\r
- QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);\r
- head.createQueryPlan(context, new EVariable(activeFact), i);\r
- body.createEnforcePlan(context, priority);\r
- constraint.plans.add(new PrioritizedPlan(priority, activeFact, context.getPlanOps()));\r
- \r
- hasActiveLiteral = true;\r
- }\r
- if(!hasActiveLiteral) {\r
- Variable activeFact = new Variable("activeFact", initConstraint.factType);\r
- QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);\r
- head.createQueryPlan(context, null, -1);\r
- body.createEnforcePlan(context, priority);\r
- /*System.out.println(this);\r
- for(PlanOp planOp : context.getPlanOps())\r
- System.out.println(" " + planOp);*/\r
- initConstraint.plans.add(new PrioritizedPlan(priority, activeFact, context.getPlanOps()));\r
- }\r
- }\r
- \r
- public String toString() {\r
- StringBuilder b = new StringBuilder();\r
- ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
- visitor.visit(this);\r
- return b.toString();\r
- }\r
- \r
-}\r
+package org.simantics.scl.compiler.elaboration.chr;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.elaboration.chr.plan.CHRSearchPlan;
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class CHRRule extends Symbol {
+ public CHRRuleset parentRuleset;
+ public int priority;
+ public CHRQuery head;
+ public CHRQuery body;
+ public Variable[] existentialVariables;
+
+ // Analysis
+ //public int firstPriorityExecuted;
+ public int lastPriorityExecuted;
+
+ // Plans
+ public ArrayList<CHRSearchPlan> plans = new ArrayList<CHRSearchPlan>();
+
+ // Code generation, move to CHRPriority
+ public String containerClassName;
+
+ public CHRRule(long location, CHRQuery head, CHRQuery body, Variable[] existentialVariables) {
+ this.location = location;
+ this.head = head;
+ this.body = body;
+ this.existentialVariables = existentialVariables;
+ }
+
+ public CHRRule(long location, CHRQuery head, CHRQuery body) {
+ this(location, head, body, null);
+ }
+
+ public void resolve(TranslationContext context) {
+ context.pushExistentialFrame();
+ head.resolve(context);
+ context.disallowNewExistentials();
+ body.resolve(context);
+ existentialVariables = context.popExistentialFrame();
+ }
+
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ head.collectRefs(allRefs, refs);
+ body.collectRefs(allRefs, refs);
+ }
+
+ public void checkType(TypingContext context) {
+ for(Variable variable : existentialVariables)
+ variable.setType(Types.metaVar(Kinds.STAR));
+ head.checkType(context);
+ body.checkType(context);
+ }
+
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+ head.collectVars(allVars, vars);
+ body.collectVars(allVars, vars);
+ }
+
+ public void collectFreeVariables(THashSet<Variable> vars) {
+ head.collectFreeVariables(vars);
+ body.collectFreeVariables(vars);
+ }
+
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ this.location = loc;
+ head.setLocationDeep(loc);
+ body.setLocationDeep(loc);
+ }
+ }
+
+ public void simplify(SimplificationContext context) {
+ head.simplify(context);
+ body.simplify(context);
+ }
+
+ public void compile(CompilationContext compilationContext, CHRConstraint initConstraint) {
+ boolean hasLocalActiveLiteral = false;
+ for(int i=0;i<head.literals.length;++i) {
+ CHRLiteral literal = head.literals[i];
+ if(literal.passive)
+ continue;
+ CHRConstraint constraint = (CHRConstraint)literal.relation;
+
+ Variable activeFact = new Variable("activeFact", constraint.factType);
+ QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
+ if(!head.createQueryPlan(context, new EVariable(activeFact), i, initConstraint))
+ return;
+ body.createEnforcePlan(context, priority);
+ addPlan(new CHRSearchPlan(constraint, activeFact, context.getPlanOps()));
+
+ if(constraint.parentRuleset == parentRuleset)
+ hasLocalActiveLiteral = true;
+ }
+ if(!hasLocalActiveLiteral) {
+ Variable activeFact = new Variable("activeFact", initConstraint.factType);
+ QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
+ if(!head.createQueryPlan(context, new EVariable(activeFact), -1, initConstraint))
+ return;
+ body.createEnforcePlan(context, priority);
+ /*System.out.println(this);
+ for(PlanOp planOp : context.getPlanOps())
+ System.out.println(" " + planOp);*/
+ addPlan(new CHRSearchPlan(initConstraint, activeFact, context.getPlanOps()));
+ }
+ }
+
+ private void addPlan(CHRSearchPlan plan) {
+ plans.add(plan);
+ }
+
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
+ visitor.visit(this);
+ return b.toString();
+ }
+
+}