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