X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fquery%2Fcompilation%2FExpressionConstraint.java;h=f8a483776488ac01f6dbd01eeea7c9c64c06e35c;hb=refs%2Fchanges%2F38%2F238%2F2;hp=c80d59f37f1f0f8191f230b343dc1644c3197fed;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java index c80d59f37..f8a483776 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.java @@ -1,114 +1,114 @@ -package org.simantics.scl.compiler.elaboration.query.compilation; - -import java.util.ArrayList; - -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; -import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; -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.errors.Locations; -import org.simantics.scl.compiler.types.TVar; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; -import gnu.trove.set.hash.TIntHashSet; - -public class ExpressionConstraint extends QueryConstraint { - Variable variable; - Expression expression; - boolean isPattern; - - long forwardVariableMask; - long backwardVariableMask; - - ArrayList globalVariables; - - public ExpressionConstraint(final ConstraintCollectionContext context, Variable variable, - Expression expression, boolean isPattern) { - this.variable = variable; - this.expression = expression; - this.isPattern = isPattern; - - final TIntHashSet vars = new TIntHashSet(); - expression.collectVars(context.getVariableMap(), vars); - - int var1 = context.variableMap.get(variable); - vars.add(var1); - backwardVariableMask = 1L << var1; - - variables = vars.toArray(); - - for(int v : variables) - forwardVariableMask |= 1L << v; - forwardVariableMask ^= backwardVariableMask; - - this.globalVariables = context.variables; - } - - private boolean canBeSolvedForwards(long boundVariables) { - return (forwardVariableMask & boundVariables) == forwardVariableMask; - } - - private boolean canBeSolvedBackwards(long boundVariables) { - return (backwardVariableMask & boundVariables) == backwardVariableMask; - } - - @Override - public boolean canBeSolvedFrom(long boundVariables) { - return canBeSolvedForwards(boundVariables) || (isPattern && canBeSolvedBackwards(boundVariables)); - } - - @Override - public double getSolutionCost(long boundVariables) { - return 1.0; - } - - @Override - public double getSolutionBranching(long boundVariables) { - if(canBeSolvedForwards(boundVariables)) - return (boundVariables&1)==0 ? 1.0 : 0.95; - else if(isPattern && canBeSolvedBackwards(boundVariables)) - return 0.95; - else - return Double.POSITIVE_INFINITY; - } - - @Override - public void generate(final QueryCompilationContext context) { - if(canBeSolvedForwards(finalBoundVariables)) { - if(canBeSolvedBackwards(finalBoundVariables)) - context.equalityCondition(expression.location, new EVariable(variable), expression); - else - context.let(variable, expression); - } - else if(canBeSolvedBackwards(finalBoundVariables)) { - Expression pattern = expression; - - long mask = forwardVariableMask & finalBoundVariables; - THashMap map = new THashMap(); - if(mask != 0L) { - for(int variableId : variables) - if( ((mask >> variableId)&1L) == 1L ) { - Variable original = globalVariables.get(variableId); - Variable newVariable = new Variable(original.getName() + "_temp", original.getType()); - map.put(original, new EVariable(newVariable)); - } - - ReplaceContext replaceContext = new ReplaceContext(new THashMap(0), map, context.getTypingContext()); - pattern = pattern.replace(replaceContext); - } - context.match(pattern, new EVariable(variable), true); - map.forEachEntry(new TObjectObjectProcedure() { - @Override - public boolean execute(Variable a, Expression b) { - context.equalityCondition(Locations.NO_LOCATION, new EVariable(a), b); - return true; - } - }); - } - else - throw new InternalCompilerError(expression.location, "Error happened when tried to solve the query."); - } -} +package org.simantics.scl.compiler.elaboration.query.compilation; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; +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.errors.Locations; +import org.simantics.scl.compiler.types.TVar; +import org.simantics.scl.compiler.types.Type; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; +import gnu.trove.set.hash.TIntHashSet; + +public class ExpressionConstraint extends QueryConstraint { + Variable variable; + Expression expression; + boolean isPattern; + + long forwardVariableMask; + long backwardVariableMask; + + ArrayList globalVariables; + + public ExpressionConstraint(final ConstraintCollectionContext context, Variable variable, + Expression expression, boolean isPattern) { + this.variable = variable; + this.expression = expression; + this.isPattern = isPattern; + + final TIntHashSet vars = new TIntHashSet(); + expression.collectVars(context.getVariableMap(), vars); + + int var1 = context.variableMap.get(variable); + vars.add(var1); + backwardVariableMask = 1L << var1; + + variables = vars.toArray(); + + for(int v : variables) + forwardVariableMask |= 1L << v; + forwardVariableMask ^= backwardVariableMask; + + this.globalVariables = context.variables; + } + + private boolean canBeSolvedForwards(long boundVariables) { + return (forwardVariableMask & boundVariables) == forwardVariableMask; + } + + private boolean canBeSolvedBackwards(long boundVariables) { + return (backwardVariableMask & boundVariables) == backwardVariableMask; + } + + @Override + public boolean canBeSolvedFrom(long boundVariables) { + return canBeSolvedForwards(boundVariables) || (isPattern && canBeSolvedBackwards(boundVariables)); + } + + @Override + public double getSolutionCost(long boundVariables) { + return 1.0; + } + + @Override + public double getSolutionBranching(long boundVariables) { + if(canBeSolvedForwards(boundVariables)) + return (boundVariables&1)==0 ? 1.0 : 0.95; + else if(isPattern && canBeSolvedBackwards(boundVariables)) + return 0.95; + else + return Double.POSITIVE_INFINITY; + } + + @Override + public void generate(final QueryCompilationContext context) { + if(canBeSolvedForwards(finalBoundVariables)) { + if(canBeSolvedBackwards(finalBoundVariables)) + context.equalityCondition(expression.location, new EVariable(variable), expression); + else + context.let(variable, expression); + } + else if(canBeSolvedBackwards(finalBoundVariables)) { + Expression pattern = expression; + + long mask = forwardVariableMask & finalBoundVariables; + THashMap map = new THashMap(); + if(mask != 0L) { + for(int variableId : variables) + if( ((mask >> variableId)&1L) == 1L ) { + Variable original = globalVariables.get(variableId); + Variable newVariable = new Variable(original.getName() + "_temp", original.getType()); + map.put(original, new EVariable(newVariable)); + } + + ReplaceContext replaceContext = new ReplaceContext(new THashMap(0), map, context.getTypingContext()); + pattern = pattern.replace(replaceContext); + } + context.match(pattern, new EVariable(variable), true); + map.forEachEntry(new TObjectObjectProcedure() { + @Override + public boolean execute(Variable a, Expression b) { + context.equalityCondition(Locations.NO_LOCATION, new EVariable(a), b); + return true; + } + }); + } + else + throw new InternalCompilerError(expression.location, "Error happened when tried to solve the query."); + } +}