1 package org.simantics.modeling.scl;
3 import org.simantics.db.Resource;
4 import org.simantics.scl.compiler.common.names.Name;
5 import org.simantics.scl.compiler.common.names.Names;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
8 import org.simantics.scl.compiler.elaboration.expressions.EApply;
9 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
10 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
11 import org.simantics.scl.compiler.elaboration.expressions.Expression;
12 import org.simantics.scl.compiler.elaboration.expressions.Variable;
13 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
14 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
15 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
16 import org.simantics.scl.compiler.environment.Environment;
17 import org.simantics.scl.compiler.errors.Locations;
18 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
19 import org.simantics.scl.compiler.types.TPred;
20 import org.simantics.scl.compiler.types.TVar;
21 import org.simantics.scl.compiler.types.Type;
22 import org.simantics.scl.compiler.types.Types;
24 public class GraphPropertyRelation implements SCLRelation {
26 Resource propertyRelation;
28 Type[] parameterTypes;
30 private static final Type RESOURCE = Types.con("Simantics/DB", "Resource");
32 public GraphPropertyRelation(Resource propertyRelation, Type valueType) {
33 this.propertyRelation = propertyRelation;
34 this.valueType = valueType;
35 this.parameterTypes = new Type[] { RESOURCE, valueType };
39 public TVar[] getTypeVariables() {
40 return TVar.EMPTY_ARRAY;
44 public TPred[] getTypeConstraints() {
45 return new TPred[] {Types.pred(Types.SERIALIZABLE, valueType)};
49 public Type[] getParameterTypes() {
50 return parameterTypes;
54 public double getSelectivity(int boundVariables) {
55 switch(boundVariables) {
57 case FB: return Double.POSITIVE_INFINITY;
60 default: throw new IllegalArgumentException();
65 public int getRequiredVariablesMask() {
69 private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue");
72 public void generate(long location, QueryCompilationContext context,
73 Type[] typeParameters, Variable[] parameters, int boundVariables) {
74 Expression possibleValue = new EApply(
75 Locations.NO_LOCATION,
77 context.getCompilationContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),
78 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
79 new EVariable(parameters[0]),
80 new EExternalConstant(propertyRelation, RESOURCE)
82 switch(boundVariables) {
84 Variable temp = new Variable("temp", valueType);
85 context.condition(new EApply(
86 context.getCompilationContext().getConstant(Names.Builtin_equals, valueType),
89 new EVariable(parameters[1])
92 context.iterateMaybe(temp, possibleValue);
94 case BF: context.iterateMaybe(parameters[1], possibleValue);
96 default: throw new IllegalArgumentException();
100 private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue");
103 public Expression generateEnforce(long location, EnforcingContext context,
104 Type[] typeParameters, Variable[] parameters) {
106 Locations.NO_LOCATION,
108 context.getCompilationContext().getConstant(CLAIM_RELATED_VALUE, valueType),
109 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
110 new EVariable(parameters[0]),
111 new EExternalConstant(propertyRelation, RESOURCE),
112 new EVariable(parameters[1])
117 public int getPhase() {
122 public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
123 Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
124 CompilationContext compilationContext = context.context;
127 context.iterateMaybe(location, w, variables[1],
129 compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
130 typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
131 expressions[0].toVal(compilationContext, w),
132 w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
135 context.checkEqualsJust(location, w, expressions[1].toVal(compilationContext, w),
137 compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
138 typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
139 expressions[0].toVal(compilationContext, w),
140 w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
142 default: throw new IllegalArgumentException();
147 public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters) {
148 CompilationContext compilationContext = context.context;
150 compilationContext.environment.getValue(CLAIM_RELATED_VALUE).getValue().createSpecialization(valueType),
151 typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
152 parameters[0].toVal(compilationContext, w),
153 w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE),
154 parameters[1].toVal(compilationContext, w));
158 public Type getEnforceEffect() {
159 return Types.WRITE_GRAPH;
163 public Type getQueryEffect() {
164 return Types.READ_GRAPH;