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.Name;
11 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
12 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
13 import org.simantics.scl.compiler.elaboration.expressions.Expressions;
14 import org.simantics.scl.compiler.elaboration.expressions.Variable;
15 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
16 import org.simantics.scl.compiler.types.TVar;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.kinds.Kinds;
21 public class LocalRelation extends AbstractRelation {
23 Type[] parameterTypes;
24 public Variable table;
26 public LocalRelation(String name, int arity) {
28 this.parameterTypes = new Type[arity];
29 for(int i=0;i<arity;++i)
30 parameterTypes[i] = Types.metaVar(Kinds.STAR);
34 public LocalRelation(String name, Type[] parameterTypes) {
36 this.parameterTypes = parameterTypes;
40 private void createTable() {
41 this.table = newVar("table" + name,
42 Types.apply(ERuleset.MSet, Types.tuple(parameterTypes)));
45 public int getArity() {
46 return parameterTypes.length;
49 public String getName() {
54 public TVar[] getTypeVariables() {
55 return TVar.EMPTY_ARRAY;
59 public Type[] getParameterTypes() {
60 return parameterTypes;
64 public double getSelectivity(int boundVariabes) {
66 for(int i=0;i<parameterTypes.length;++i,boundVariabes>>=1)
67 if( (boundVariabes&1) == 0 )
73 public int getRequiredVariablesMask() {
77 private static final Name MSet_contains = Name.create("MSet", "contains");
78 private static final Name EQ = Name.create("Prelude", "==");
80 public void generate(long location,
81 QueryCompilationContext context,
82 Type[] typeParameters, Variable[] parameters, int boundVariables) {
84 throw new InternalCompilerError(location, "Variable table is undefined.");
85 if(boundVariables + 1 == 1 << parameters.length)
86 context.condition(apply(context, Types.PROC,
87 MSet_contains, Types.tuple(parameterTypes),
89 tuple(vars(parameters))
92 Variable[] aux = new Variable[parameters.length];
93 for(int i=0;i<parameters.length;++i)
94 if(((boundVariables>>i)&1) == 1)
95 aux[i] = new Variable("aux_" + parameters[i].getName(), parameters[i].getType());
97 aux[i] = parameters[i];
98 Variable row = new Variable("row", Types.tuple(parameterTypes));
99 for(int i=0;i<parameters.length;++i)
100 if(((boundVariables>>i)&1) == 1)
101 context.condition(apply(context, Types.NO_EFFECTS,
102 EQ, parameterTypes[i],
103 context.getEvidence(location, Types.pred(Types.EQ, parameterTypes[i])),
107 context.match(Expressions.tuple(Expressions.vars(aux)), new EVariable(row), false);
108 context.iterateMSet(row, new EVariable(table));
113 public String toString() {