1 package org.simantics.scl.compiler.elaboration.relations;
3 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.common.names.Name;
7 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
8 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
9 import org.simantics.scl.compiler.elaboration.expressions.Expressions;
10 import org.simantics.scl.compiler.elaboration.expressions.Variable;
11 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
12 import org.simantics.scl.compiler.types.TVar;
13 import org.simantics.scl.compiler.types.Type;
14 import org.simantics.scl.compiler.types.Types;
15 import org.simantics.scl.compiler.types.kinds.Kinds;
17 public class LocalRelation extends AbstractRelation {
19 Type[] parameterTypes;
20 public Variable table;
22 public LocalRelation(String name, int arity) {
24 this.parameterTypes = new Type[arity];
25 for(int i=0;i<arity;++i)
26 parameterTypes[i] = Types.metaVar(Kinds.STAR);
30 public LocalRelation(String name, Type[] parameterTypes) {
32 this.parameterTypes = parameterTypes;
36 private void createTable() {
37 this.table = newVar("table" + name,
38 Types.apply(ERuleset.MSet, Types.tuple(parameterTypes)));
41 public int getArity() {
42 return parameterTypes.length;
45 public String getName() {
50 public TVar[] getTypeVariables() {
51 return TVar.EMPTY_ARRAY;
55 public Type[] getParameterTypes() {
56 return parameterTypes;
60 public double getSelectivity(int boundVariabes) {
62 for(int i=0;i<parameterTypes.length;++i,boundVariabes>>=1)
63 if( (boundVariabes&1) == 0 )
69 public int getRequiredVariablesMask() {
73 private static final Name MSet_contains = Name.create("MSet", "contains");
74 private static final Name EQ = Name.create("Prelude", "==");
76 public void generate(long location,
77 QueryCompilationContext context,
78 Type[] typeParameters, Variable[] parameters, int boundVariables) {
80 throw new InternalCompilerError(location, "Variable table is undefined.");
81 if(boundVariables + 1 == 1 << parameters.length)
82 context.condition(apply(context, Types.PROC,
83 MSet_contains, Types.tuple(parameterTypes),
85 tuple(vars(parameters))
88 Variable[] aux = new Variable[parameters.length];
89 for(int i=0;i<parameters.length;++i)
90 if(((boundVariables>>i)&1) == 1)
91 aux[i] = new Variable("aux_" + parameters[i].getName(), parameters[i].getType());
93 aux[i] = parameters[i];
94 Variable row = new Variable("row", Types.tuple(parameterTypes));
95 for(int i=0;i<parameters.length;++i)
96 if(((boundVariables>>i)&1) == 1)
97 context.condition(apply(context, Types.NO_EFFECTS,
98 EQ, parameterTypes[i],
99 context.getEvidence(location, Types.pred(Types.EQ, 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() {