]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java
(refs #7377) Refactoring CHR query parsing
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRRule.java
1 package org.simantics.scl.compiler.elaboration.chr;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.compilation.CompilationContext;
6 import org.simantics.scl.compiler.elaboration.chr.plan.CHRSearchPlan;
7 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
8 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
9 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
10 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
11 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
12 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
13 import org.simantics.scl.compiler.elaboration.expressions.Variable;
14 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
15 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
16 import org.simantics.scl.compiler.errors.Locations;
17 import org.simantics.scl.compiler.internal.parsing.Symbol;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.kinds.Kinds;
20
21 import gnu.trove.map.hash.TObjectIntHashMap;
22 import gnu.trove.set.hash.THashSet;
23 import gnu.trove.set.hash.TIntHashSet;
24
25 public class CHRRule extends Symbol {
26     public CHRRuleset parentRuleset;
27     public int priority;
28     public CHRQuery head;
29     public CHRQuery body;
30     public Variable[] existentialVariables;
31     
32     // Analysis
33     //public int firstPriorityExecuted;
34     public int lastPriorityExecuted;
35     
36     // Plans
37     public ArrayList<CHRSearchPlan> plans = new ArrayList<CHRSearchPlan>();
38     
39     // Code generation, move to CHRPriority
40     public String containerClassName;
41     
42     public CHRRule(long location, CHRQuery head, CHRQuery body, Variable[] existentialVariables) {
43         this.location = location;
44         this.head = head;
45         this.body = body;
46         this.existentialVariables = existentialVariables;
47     }
48     
49     public CHRRule(long location, CHRQuery head, CHRQuery body) {
50         this(location, head, body, null);
51     }
52
53     public void resolve(TranslationContext context) {
54         context.pushExistentialFrame();
55         head.resolve(context);
56         context.disallowNewExistentials();
57         body.resolve(context);
58         existentialVariables = context.popExistentialFrame();
59     }
60
61     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
62         head.collectRefs(allRefs, refs);
63         body.collectRefs(allRefs, refs);
64     }
65
66     public void checkType(TypingContext context) {
67         for(Variable variable : existentialVariables)
68             variable.setType(Types.metaVar(Kinds.STAR));
69         head.checkType(context);
70         body.checkType(context);
71     }
72     
73     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
74         head.collectVars(allVars, vars);
75         body.collectVars(allVars, vars);
76     }
77
78     public void forVariables(VariableProcedure procedure) {
79         head.forVariables(procedure);
80         body.forVariables(procedure);
81     }
82
83     public void collectFreeVariables(THashSet<Variable> vars) {
84         head.collectFreeVariables(vars);
85         body.collectFreeVariables(vars);
86     }
87
88     public void setLocationDeep(long loc) {
89         if(location == Locations.NO_LOCATION) {
90             this.location = loc;
91             head.setLocationDeep(loc);
92             body.setLocationDeep(loc);
93         }
94     }
95     
96     public void simplify(SimplificationContext context) {
97         head.simplify(context);
98         body.simplify(context);
99     }
100
101     public void compile(CompilationContext compilationContext, CHRConstraint initConstraint) {
102         boolean hasLocalActiveLiteral = false;
103         for(int i=0;i<head.literals.length;++i) {
104             CHRLiteral literal = head.literals[i];
105             if(literal.passive)
106                 continue;
107             CHRConstraint constraint = (CHRConstraint)literal.relation;
108             
109             Variable activeFact = new Variable("activeFact", constraint.factType);
110             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
111             if(!head.createQueryPlan(context, new EVariable(activeFact), i, initConstraint))
112                 return;
113             body.createEnforcePlan(context, priority);
114             addPlan(new CHRSearchPlan(constraint, activeFact, context.getPlanOps()));
115             
116             if(constraint.parentRuleset == parentRuleset)
117                 hasLocalActiveLiteral = true;
118         }
119         if(!hasLocalActiveLiteral) {
120             Variable activeFact = new Variable("activeFact", initConstraint.factType);
121             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
122             if(!head.createQueryPlan(context, new EVariable(activeFact), -1, initConstraint))
123                 return;
124             body.createEnforcePlan(context, priority);
125             /*System.out.println(this);
126             for(PlanOp planOp : context.getPlanOps())
127                 System.out.println("    " + planOp);*/
128             addPlan(new CHRSearchPlan(initConstraint, activeFact, context.getPlanOps()));
129         }
130     }
131     
132     private void addPlan(CHRSearchPlan plan) {
133         plans.add(plan);
134     }
135
136     public String toString() {
137         StringBuilder b = new StringBuilder();
138         ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
139         visitor.visit(this);
140         return b.toString();
141     }
142     
143 }