1 package org.simantics.modeling.scl;
\r
3 import org.simantics.db.Resource;
\r
4 import org.simantics.scl.compiler.common.names.Name;
\r
5 import org.simantics.scl.compiler.elaboration.expressions.EApply;
\r
6 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
\r
7 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
\r
8 import org.simantics.scl.compiler.elaboration.expressions.Expression;
\r
9 import org.simantics.scl.compiler.elaboration.expressions.Variable;
\r
10 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
\r
11 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
\r
12 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
\r
13 import org.simantics.scl.compiler.errors.Locations;
\r
14 import org.simantics.scl.compiler.types.TVar;
\r
15 import org.simantics.scl.compiler.types.Type;
\r
16 import org.simantics.scl.compiler.types.Types;
\r
18 public class GraphPropertyRelation implements SCLRelation {
\r
20 Resource propertyRelation;
\r
22 Type[] parameterTypes;
\r
24 private static final Type RESOURCE = Types.con("Simantics/DB", "Resource");
\r
26 public GraphPropertyRelation(Resource propertyRelation, Type valueType) {
\r
27 this.propertyRelation = propertyRelation;
\r
28 this.valueType = valueType;
\r
29 this.parameterTypes = new Type[] { RESOURCE, valueType };
\r
33 public TVar[] getTypeVariables() {
\r
34 return TVar.EMPTY_ARRAY;
\r
38 public Type[] getParameterTypes() {
\r
39 return parameterTypes;
\r
43 public double getSelectivity(int boundVariables) {
\r
44 switch(boundVariables) {
\r
46 case FB: return Double.POSITIVE_INFINITY;
\r
47 case BF: return 1.0;
\r
48 case BB: return 0.01;
\r
49 default: throw new IllegalArgumentException();
\r
54 public int getRequiredVariablesMask() {
\r
58 private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue");
\r
61 public void generate(long location, QueryCompilationContext context,
\r
62 Type[] typeParameters, Variable[] parameters, int boundVariables) {
\r
63 Expression possibleValue = new EApply(
\r
64 Locations.NO_LOCATION,
\r
66 context.getTypingContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),
\r
67 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
\r
68 new EVariable(parameters[0]),
\r
69 new EExternalConstant(propertyRelation, RESOURCE)
\r
71 switch(boundVariables) {
\r
73 Variable temp = new Variable("temp", valueType);
\r
74 context.condition(new EApply(
\r
75 context.getTypingContext().getConstant(Name.create("Prelude", "=="), valueType),
\r
77 context.getEvidence(location, Types.pred(Types.EQ, valueType)),
\r
78 new EVariable(temp),
\r
79 new EVariable(parameters[1])
\r
82 context.iterateMaybe(temp, possibleValue);
\r
84 case BF: context.iterateMaybe(parameters[1], possibleValue);
\r
86 default: throw new IllegalArgumentException();
\r
90 private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue");
\r
93 public Expression generateEnforce(long location, EnforcingContext context,
\r
94 Type[] typeParameters, Variable[] parameters) {
\r
96 Locations.NO_LOCATION,
\r
98 context.getTypingContext().getConstant(CLAIM_RELATED_VALUE, valueType),
\r
99 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
\r
100 new EVariable(parameters[0]),
\r
101 new EExternalConstant(propertyRelation, RESOURCE),
\r
102 new EVariable(parameters[1])
\r
107 public int getPhase() {
\r