]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java
Merge "Trying to wait for procedures"
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / ontologymodule / GraphRelation.java
1 package org.simantics.modeling.scl.ontologymodule;
2
3 import org.simantics.db.Resource;
4 import org.simantics.scl.compiler.common.names.Name;
5 import org.simantics.scl.compiler.compilation.CompilationContext;
6 import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;
8 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
9 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;
12 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
13 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
14 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
15 import org.simantics.scl.compiler.errors.Locations;
16 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
17 import org.simantics.scl.compiler.types.TVar;
18 import org.simantics.scl.compiler.types.Type;
19 import org.simantics.scl.compiler.types.Types;
20
21 public class GraphRelation implements SCLRelation {
22
23     Resource relation;
24     double relationSelectivity;
25     Resource inverseRelation;
26     double inverseRelationSelectivity;
27     
28     public GraphRelation(Resource relation, double relationSelectivity,
29             Resource inverseRelation, double inverseRelationSelectivity) {
30         this.relation = relation;
31         this.relationSelectivity = relationSelectivity;
32         this.inverseRelation = inverseRelation;
33         this.inverseRelationSelectivity = inverseRelationSelectivity;
34     }
35
36     @Override
37     public TVar[] getTypeVariables() {
38         return TVar.EMPTY_ARRAY;
39     }
40     
41     private static final Type[] PARAMETER_TYPES = new Type[] { Types.RESOURCE, Types.RESOURCE };
42     
43     @Override
44     public Type[] getParameterTypes() {
45         return PARAMETER_TYPES;
46     }
47
48     @Override
49     public double getSelectivity(int boundVariables) {
50         switch(boundVariables) {
51         case FF: return Double.POSITIVE_INFINITY;
52         case BF: return relationSelectivity;
53         case FB: return inverseRelation == null ? Double.POSITIVE_INFINITY : inverseRelationSelectivity;
54         case BB: return 0.1;
55         default: throw new IllegalArgumentException();
56         }
57     }
58     
59     @Override
60     public int getRequiredVariablesMask() {
61         return inverseRelation == null ? BF : FF;
62     }
63     
64     private static final Name GET_OBJECTS = Name.create("Simantics/DB", "#");
65     private static final Name HAS_STATEMENT = Name.create("Simantics/DB", "existsStatement3");
66     
67     @Override
68     public void generate(long location, QueryCompilationContext context,
69             Type[] typeParameters, Variable[] parameters, int boundVariables) {
70         switch(boundVariables) {
71         case BF: 
72             context.iterateList(parameters[1], new EApply(
73                     Locations.NO_LOCATION,
74                     Types.READ_GRAPH,
75                     context.getCompilationContext().getConstant(GET_OBJECTS),
76                     new EVariable(parameters[0]),
77                     new EExternalConstant(relation, Types.RESOURCE)
78                     ));
79             break;
80         case FB:
81             if(inverseRelation == null)
82                 throw new IllegalArgumentException();
83             context.iterateList(parameters[0], new EApply(
84                     Locations.NO_LOCATION,
85                     Types.READ_GRAPH,
86                     context.getCompilationContext().getConstant(GET_OBJECTS),
87                     new EVariable(parameters[1]),
88                     new EExternalConstant(inverseRelation, Types.RESOURCE)
89                     ));
90             break;
91         case BB:
92             context.condition(
93                     inverseRelation == null || relationSelectivity <= inverseRelationSelectivity
94                     ? new EApply(
95                             Locations.NO_LOCATION,
96                             Types.READ_GRAPH,
97                             context.getCompilationContext().getConstant(HAS_STATEMENT),
98                             new Expression[] {
99                                 new EVariable(parameters[0]),
100                                 new EExternalConstant(relation, Types.RESOURCE),
101                                 new EVariable(parameters[1])
102                             }
103                             )
104                     : new EApply(
105                             Locations.NO_LOCATION,
106                             Types.READ_GRAPH,
107                             context.getCompilationContext().getConstant(HAS_STATEMENT),
108                             new Expression[] {
109                                 new EVariable(parameters[1]),
110                                 new EExternalConstant(inverseRelation, Types.RESOURCE),
111                                 new EVariable(parameters[0])
112                             }
113                             ));
114             break;
115         default: throw new IllegalArgumentException();
116         }
117     }
118
119     private static final Name CLAIM = Name.create("Simantics/DB", "claim");
120     
121     @Override
122     public Expression generateEnforce(long location, EnforcingContext context,
123             Type[] typeParameters, Variable[] parameters) {
124         return new EApply(
125                 Locations.NO_LOCATION,
126                 Types.WRITE_GRAPH,
127                 context.getCompilationContext().getConstant(CLAIM),
128                 new EVariable(parameters[0]),
129                 new EExternalConstant(relation, Types.RESOURCE),
130                 new EVariable(parameters[1])
131                 );
132     }
133
134     @Override
135     public int getPhase() {
136         return 0;
137     }
138
139     @Override
140     public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
141             Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
142         CompilationContext compilationContext = context.context;
143         switch(boundMask) {
144         case BF:
145             context.iterateList(location, w, variables[1],
146                     w.apply(location,
147                             compilationContext.environment.getValue(GET_OBJECTS).getValue(),
148                             expressions[0].toVal(compilationContext, w),
149                             w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE)));
150             break;
151         case FB:
152             if(inverseRelation == null)
153                 throw new IllegalArgumentException();
154             context.iterateList(location, w, variables[0],
155                     w.apply(location,
156                             compilationContext.environment.getValue(GET_OBJECTS).getValue(),
157                             expressions[1].toVal(compilationContext, w),
158                             w.getModuleWriter().getExternalConstant(inverseRelation, Types.RESOURCE)));
159             break;
160         case BB:
161             context.check(location, w, 
162                     inverseRelation == null || relationSelectivity <= inverseRelationSelectivity
163                     ? w.apply(location, compilationContext.environment.getValue(HAS_STATEMENT).getValue(), 
164                             expressions[0].toVal(compilationContext, w),
165                             w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE),
166                             expressions[1].toVal(compilationContext, w))
167                     : w.apply(location, compilationContext.environment.getValue(HAS_STATEMENT).getValue(), 
168                             expressions[1].toVal(compilationContext, w),
169                             w.getModuleWriter().getExternalConstant(inverseRelation, Types.RESOURCE),
170                             expressions[0].toVal(compilationContext, w)));
171             break;
172         default: throw new IllegalArgumentException();
173         }
174     }
175
176     @Override
177     public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters,
178             Expression[] typeConstraintEvidenceParameters) {
179         CompilationContext compilationContext = context.context;
180         w.apply(location,
181                 compilationContext.environment.getValue(CLAIM).getValue(),
182                 parameters[0].toVal(compilationContext, w),
183                 w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE),
184                 parameters[1].toVal(compilationContext, w));
185     }
186     
187     @Override
188     public Type getEnforceEffect() {
189         return Types.WRITE_GRAPH;
190     }
191
192     @Override
193     public Type getQueryEffect() {
194         return Types.READ_GRAPH;
195     }
196 }