]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java
(refs #7250) CHR rules modularization (first working version)
[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.junit.runners.ParentRunner;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.elaboration.chr.plan.CHRSearchPlan;
8 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
9 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
10 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
11 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
12 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
13 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
14 import org.simantics.scl.compiler.elaboration.expressions.Variable;
15 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
16 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
17 import org.simantics.scl.compiler.errors.Locations;
18 import org.simantics.scl.compiler.internal.parsing.Symbol;
19 import org.simantics.scl.compiler.types.Types;
20 import org.simantics.scl.compiler.types.kinds.Kinds;
21
22 import gnu.trove.map.hash.TObjectIntHashMap;
23 import gnu.trove.set.hash.THashSet;
24 import gnu.trove.set.hash.TIntHashSet;
25
26 public class CHRRule extends Symbol {
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 void resolve(TranslationContext context) {
50         context.pushExistentialFrame();
51         head.resolve(context);
52         body.resolve(context);
53         existentialVariables = context.popExistentialFrame();
54     }
55
56     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
57         head.collectRefs(allRefs, refs);
58         body.collectRefs(allRefs, refs);
59     }
60
61     public void checkType(TypingContext context) {
62         for(Variable variable : existentialVariables)
63             variable.setType(Types.metaVar(Kinds.STAR));
64         head.checkType(context);
65         body.checkType(context);
66     }
67     
68     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
69         head.collectVars(allVars, vars);
70         body.collectVars(allVars, vars);
71     }
72
73     public void forVariables(VariableProcedure procedure) {
74         head.forVariables(procedure);
75         body.forVariables(procedure);
76     }
77
78     public void collectFreeVariables(THashSet<Variable> vars) {
79         head.collectFreeVariables(vars);
80         body.collectFreeVariables(vars);
81     }
82
83     public void setLocationDeep(long loc) {
84         if(location == Locations.NO_LOCATION) {
85             this.location = loc;
86             head.setLocationDeep(loc);
87             body.setLocationDeep(loc);
88         }
89     }
90     
91     public void simplify(SimplificationContext context) {
92         head.simplify(context);
93         body.simplify(context);
94     }
95
96     public void compile(CompilationContext compilationContext, CHRConstraint initConstraint) {
97         boolean hasActiveLiteral = false;
98         for(int i=0;i<head.literals.length;++i) {
99             CHRLiteral literal = head.literals[i];
100             if(literal.passive)
101                 continue;
102             CHRConstraint constraint = (CHRConstraint)literal.relation;
103             
104             Variable activeFact = new Variable("activeFact", constraint.factType);
105             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
106             if(!head.createQueryPlan(context, new EVariable(activeFact), i))
107                 return;
108             body.createEnforcePlan(context, priority);
109             addPlan(new CHRSearchPlan(constraint, activeFact, context.getPlanOps()));
110             
111             hasActiveLiteral = true;
112         }
113         if(!hasActiveLiteral) {
114             Variable activeFact = new Variable("activeFact", initConstraint.factType);
115             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
116             if(!head.createQueryPlan(context, null, -1))
117                 return;
118             body.createEnforcePlan(context, priority);
119             /*System.out.println(this);
120             for(PlanOp planOp : context.getPlanOps())
121                 System.out.println("    " + planOp);*/
122             addPlan(new CHRSearchPlan(initConstraint, activeFact, context.getPlanOps()));
123         }
124     }
125     
126     private void addPlan(CHRSearchPlan plan) {
127         plans.add(plan);
128     }
129
130     public String toString() {
131         StringBuilder b = new StringBuilder();
132         ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
133         visitor.visit(this);
134         return b.toString();
135     }
136     
137 }