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> v)&1) != 0) localBoundVariables |= 1 << i; } return localBoundVariables; } @Override public String toString() { return atom.toString(); } }