X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fscl%2Fontologymodule%2FGraphPropertyRelation.java;fp=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fscl%2Fontologymodule%2FGraphPropertyRelation.java;h=3275656bc2021312607b35b0087c8016058838ec;hb=6320ecb3f75e3a29ed620ca5425ca22ef88a5496;hp=0000000000000000000000000000000000000000;hpb=6d789e04560b01a1845d39f7e951230bb74d6470;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java new file mode 100644 index 000000000..3275656bc --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java @@ -0,0 +1,166 @@ +package org.simantics.modeling.scl.ontologymodule; + +import org.simantics.db.Resource; +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.common.names.Names; +import org.simantics.scl.compiler.compilation.CompilationContext; +import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext; +import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext; +import org.simantics.scl.compiler.elaboration.relations.SCLRelation; +import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.errors.Locations; +import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; +import org.simantics.scl.compiler.types.TPred; +import org.simantics.scl.compiler.types.TVar; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; + +public class GraphPropertyRelation implements SCLRelation { + + Resource propertyRelation; + Type valueType; + Type[] parameterTypes; + + private static final Type RESOURCE = Types.con("Simantics/DB", "Resource"); + + public GraphPropertyRelation(Resource propertyRelation, Type valueType) { + this.propertyRelation = propertyRelation; + this.valueType = valueType; + this.parameterTypes = new Type[] { RESOURCE, valueType }; + } + + @Override + public TVar[] getTypeVariables() { + return TVar.EMPTY_ARRAY; + } + + @Override + public TPred[] getTypeConstraints() { + return new TPred[] {Types.pred(Types.SERIALIZABLE, valueType)}; + } + + @Override + public Type[] getParameterTypes() { + return parameterTypes; + } + + @Override + public double getSelectivity(int boundVariables) { + switch(boundVariables) { + case FF: + case FB: return Double.POSITIVE_INFINITY; + case BF: return 1.0; + case BB: return 0.01; + default: throw new IllegalArgumentException(); + } + } + + @Override + public int getRequiredVariablesMask() { + return BF; + } + + private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue"); + + @Override + public void generate(long location, QueryCompilationContext context, + Type[] typeParameters, Variable[] parameters, int boundVariables) { + Expression possibleValue = new EApply( + Locations.NO_LOCATION, + Types.READ_GRAPH, + context.getCompilationContext().getConstant(POSSIBLE_RELATED_VALUE, valueType), + context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)), + new EVariable(parameters[0]), + new EExternalConstant(propertyRelation, RESOURCE) + ); + switch(boundVariables) { + case BB: { + Variable temp = new Variable("temp", valueType); + context.condition(new EApply( + context.getCompilationContext().getConstant(Names.Builtin_equals, valueType), + new Expression[] { + new EVariable(temp), + new EVariable(parameters[1]) + } + )); + context.iterateMaybe(temp, possibleValue); + } break; + case BF: context.iterateMaybe(parameters[1], possibleValue); + break; + default: throw new IllegalArgumentException(); + } + } + + private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue"); + + @Override + public Expression generateEnforce(long location, EnforcingContext context, + Type[] typeParameters, Variable[] parameters) { + return new EApply( + Locations.NO_LOCATION, + Types.WRITE_GRAPH, + context.getCompilationContext().getConstant(CLAIM_RELATED_VALUE, valueType), + context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)), + new EVariable(parameters[0]), + new EExternalConstant(propertyRelation, RESOURCE), + new EVariable(parameters[1]) + ); + } + + @Override + public int getPhase() { + return 0; + } + + @Override + public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, + Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { + CompilationContext compilationContext = context.context; + switch(boundMask) { + case BF: + context.iterateMaybe(location, w, variables[1], + w.apply(location, + compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(compilationContext, w), + expressions[0].toVal(compilationContext, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE))); + break; + case BB: + context.checkEqualsJust(location, w, expressions[1].toVal(compilationContext, w), + w.apply(location, + compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(compilationContext, w), + expressions[0].toVal(compilationContext, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE))); + break; + default: throw new IllegalArgumentException(); + } + } + + @Override + public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters) { + CompilationContext compilationContext = context.context; + w.apply(location, + compilationContext.environment.getValue(CLAIM_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(compilationContext, w), + parameters[0].toVal(compilationContext, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE), + parameters[1].toVal(compilationContext, w)); + } + + @Override + public Type getEnforceEffect() { + return Types.WRITE_GRAPH; + } + + @Override + public Type getQueryEffect() { + return Types.READ_GRAPH; + } +}