1 package org.simantics.scl.compiler.elaboration.relations;
3 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
4 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.newVar;
5 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple;
6 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
7 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
9 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
10 import org.simantics.scl.compiler.common.names.Names;
11 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
12 import org.simantics.scl.compiler.elaboration.expressions.Expressions;
13 import org.simantics.scl.compiler.elaboration.expressions.Variable;
14 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
15 import org.simantics.scl.compiler.types.TVar;
16 import org.simantics.scl.compiler.types.Type;
17 import org.simantics.scl.compiler.types.Types;
18 import org.simantics.scl.compiler.types.kinds.Kinds;
20 public class LocalRelation extends AbstractRelation {
22 Type[] parameterTypes;
23 public Variable table;
25 public LocalRelation(String name, int arity) {
27 this.parameterTypes = new Type[arity];
28 for(int i=0;i<arity;++i)
29 parameterTypes[i] = Types.metaVar(Kinds.STAR);
33 public LocalRelation(String name, Type[] parameterTypes) {
35 this.parameterTypes = parameterTypes;
39 private void createTable() {
40 this.table = newVar("table" + name,
41 Types.apply(Names.MSet_T, Types.tuple(parameterTypes)));
44 public int getArity() {
45 return parameterTypes.length;
48 public String getName() {
53 public TVar[] getTypeVariables() {
54 return TVar.EMPTY_ARRAY;
58 public Type[] getParameterTypes() {
59 return parameterTypes;
63 public double getSelectivity(int boundVariabes) {
65 for(int i=0;i<parameterTypes.length;++i,boundVariabes>>=1)
66 if( (boundVariabes&1) == 0 )
72 public int getRequiredVariablesMask() {
77 public void generate(long location,
78 QueryCompilationContext context,
79 Type[] typeParameters, Variable[] parameters, int boundVariables) {
81 throw new InternalCompilerError(location, "Variable table is undefined.");
82 if(boundVariables + 1 == 1 << parameters.length)
83 context.condition(apply(context.getCompilationContext(), Types.PROC,
84 Names.MSet_contains, Types.tuple(parameterTypes),
86 tuple(vars(parameters))
89 Variable[] aux = new Variable[parameters.length];
90 for(int i=0;i<parameters.length;++i)
91 if(((boundVariables>>i)&1) == 1)
92 aux[i] = new Variable("aux_" + parameters[i].getName(), parameters[i].getType());
94 aux[i] = parameters[i];
95 Variable row = new Variable("row", Types.tuple(parameterTypes));
96 for(int i=0;i<parameters.length;++i)
97 if(((boundVariables>>i)&1) == 1)
98 context.condition(apply(context.getCompilationContext(), Types.NO_EFFECTS,
99 Names.Builtin_equals, parameterTypes[i],
103 context.match(Expressions.tuple(Expressions.vars(aux)), new EVariable(row), false);
104 context.iterateMSet(row, new EVariable(table));
109 public String toString() {