package org.simantics.scl.compiler.elaboration.query; import java.util.Collection; import java.util.Set; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; import org.simantics.scl.compiler.elaboration.expressions.Variable; 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.UnsolvableQueryException; import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; public class QExists extends QAbstractModifier { Variable[] variables; public QExists(Variable[] variables, Query query) { super(query); this.variables = variables; } public QExists(Collection variables, Query query) { this(variables.toArray(new Variable[variables.size()]), query); } @Override public void collectFreeVariables(THashSet vars) { super.collectFreeVariables(vars); for(Variable variable : variables) vars.remove(variable); } @Override public void checkType(TypingContext context) { for(Variable var : variables) var.setType(Types.metaVar(Kinds.STAR)); super.checkType(context); } @Override public void collectConstraints(ConstraintCollectionContext context) throws UnsolvableQueryException { for(Variable variable : variables) context.addVariable(variable); query.collectConstraints(context); } @Override public Diff[] derivate(THashMap diffables) throws DerivateException { Diff[] result = query.derivate(diffables); for(int i=0;i relations) { Query newQuery = query.removeRelations(relations); if(newQuery == query) return this; else if(newQuery == EMPTY_QUERY) return EMPTY_QUERY; else return new QExists(variables, newQuery); } @Override public void accept(QueryVisitor visitor) { visitor.visit(this); } @Override public Query accept(QueryTransformer transformer) { return transformer.transform(this); } }