]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/RelationConstraint.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / query / compilation / RelationConstraint.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/RelationConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/RelationConstraint.java
new file mode 100644 (file)
index 0000000..b9106d3
--- /dev/null
@@ -0,0 +1,67 @@
+package org.simantics.scl.compiler.elaboration.query.compilation;
+
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+
+public class RelationConstraint extends QueryConstraint {
+
+    // static
+    QAtom atom;
+    
+    int[] optionalVariableByParameter;
+    Variable[] parameters;
+
+    long requiredVariablesMask;
+    
+    public RelationConstraint(int[] variables, Variable[] parameters, QAtom atom, int[] optionalVariableByParameter,
+            long requiredVariablesMask) {
+        super(variables);
+        this.atom = atom;
+        this.parameters = parameters;
+        this.optionalVariableByParameter = optionalVariableByParameter;
+        this.requiredVariablesMask = requiredVariablesMask;
+    }
+
+    @Override
+    public boolean canBeSolvedFrom(long boundVariables) {
+        return getSolutionBranching(boundVariables) != Double.POSITIVE_INFINITY;
+    }
+    
+    @Override
+    public double getSolutionBranching(long boundVariables) {
+        if( (boundVariables&requiredVariablesMask) != requiredVariablesMask )
+            return Double.POSITIVE_INFINITY;        
+        return atom.relation.getSelectivity(getLocalBoundVariables(boundVariables));
+    }
+    
+    @Override
+    public double getSolutionCost(long boundVariables) {
+        return 1.0;
+    }
+    
+    @Override
+    public void generate(QueryCompilationContext context) {
+        atom.relation.generate(atom.location, 
+                context, atom.typeParameters,
+                parameters, getLocalBoundVariables(finalBoundVariables));
+        for(int i=atom.parameters.length-1;i>=0;--i)
+            if(optionalVariableByParameter[i] < 0 && !(atom.parameters[i] instanceof EVariable))
+                context.let(parameters[i], atom.parameters[i]);
+    }
+    
+    private int getLocalBoundVariables(long boundVariables) {
+        int localBoundVariables = 0;
+        for(int i=0;i<optionalVariableByParameter.length;++i) {
+            int v = optionalVariableByParameter[i]; 
+            if(v < 0 || ((boundVariables >> v)&1) != 0)
+                localBoundVariables |= 1 << i;
+        }
+        return localBoundVariables;
+    }
+    
+    @Override
+    public String toString() {
+        return atom.toString();
+    }
+}