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%2FQNegation.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fquery%2FQNegation.java;h=20147c7dfd21288b43637019ebd196857d1beb2a;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java new file mode 100644 index 000000000..20147c7df --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.java @@ -0,0 +1,93 @@ +package org.simantics.scl.compiler.elaboration.query; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.TIntHashSet; + +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; +import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; +import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException; +import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext; +import org.simantics.scl.compiler.elaboration.query.compilation.QueryConstraint; +import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; +import org.simantics.scl.compiler.elaboration.relations.LocalRelation; +import org.simantics.scl.compiler.types.Type; + + +public class QNegation extends QAbstractModifier { + + public QNegation(Query query) { + super(query); + } + + @Override + public void collectConstraints(ConstraintCollectionContext context) throws UnsolvableQueryException { + TIntHashSet vars = new TIntHashSet(); + query.collectVars(context.getVariableMap(), vars); + + final QueryCompilationContext innerContext = context.getQueryCompilationContext().createCheckContext(); + query.generate(innerContext); + + context.addConstraint(new QueryConstraint(vars.toArray()) { + long variableMask; + { + for(int v : variables) + variableMask |= 1L << v; + } + @Override + public double getSolutionCost(long boundVariables) { + if((boundVariables & variableMask) != variableMask) + return Double.POSITIVE_INFINITY; + return innerContext.getCost(); + } + @Override + public double getSolutionBranching(long boundVariables) { + if((boundVariables & variableMask) != variableMask) + return Double.POSITIVE_INFINITY; + return innerContext.getBranching(); + } + @Override + public boolean canBeSolvedFrom(long boundVariables) { + return (boundVariables & variableMask) == variableMask; + } + + @Override + public long getVariableMask() { + return variableMask; + } + @Override + public void generate(QueryCompilationContext context) { + context.condition(new EApply( + context.getConstant(Name.create("Prelude", "not"), Type.EMPTY_ARRAY), + innerContext.getContinuation())); + } + }); + } + + @Override + public Query replace(ReplaceContext context) { + return new QNegation(query.replace(context)); + } + + @Override + public Diff[] derivate(THashMap diffables) throws DerivateException { + Diff[] diffs = query.derivate(diffables); + if(diffs.length == 0) + return NO_DIFF; + else + throw new DerivateException(location); + } + + @Override + public void accept(QueryVisitor visitor) { + visitor.visit(this); + } + + @Override + public Query accept(QueryTransformer transformer) { + return transformer.transform(this); + } + +}