]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java
3fbeef75525671c41daee45dbd80e8b9213015f2
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / relations / LocalRelation.java
1 package org.simantics.scl.compiler.elaboration.relations;
2
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;
8
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;
19
20 public class LocalRelation extends AbstractRelation {
21     String name;
22     Type[] parameterTypes;
23     public Variable table;
24     
25     public LocalRelation(String name, int arity) {
26         this.name = name;
27         this.parameterTypes = new Type[arity];
28         for(int i=0;i<arity;++i)
29             parameterTypes[i] = Types.metaVar(Kinds.STAR);
30         createTable();
31     }
32     
33     public LocalRelation(String name, Type[] parameterTypes) {
34         this.name = name;
35         this.parameterTypes = parameterTypes;
36         createTable();
37     }
38     
39     private void createTable() {
40         this.table = newVar("table" + name, 
41                 Types.apply(Names.MSet_T, Types.tuple(parameterTypes)));
42     }
43     
44     public int getArity() {
45         return parameterTypes.length;
46     }
47
48     public String getName() {
49         return name;
50     }
51     
52     @Override
53     public TVar[] getTypeVariables() {
54         return TVar.EMPTY_ARRAY;
55     }
56
57     @Override
58     public Type[] getParameterTypes() {
59         return parameterTypes;
60     }
61     
62     @Override
63     public double getSelectivity(int boundVariabes) {
64         double s = 0.95;
65         for(int i=0;i<parameterTypes.length;++i,boundVariabes>>=1)
66             if( (boundVariabes&1) == 0 )
67                 s *= 10.0;
68         return s;
69     }
70     
71     @Override
72     public int getRequiredVariablesMask() {
73         return 0;
74     }
75     
76     @Override
77     public void generate(long location,
78             QueryCompilationContext context,
79             Type[] typeParameters, Variable[] parameters, int boundVariables) {
80         if(table == null)
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),
85                     var(table),
86                     tuple(vars(parameters))
87                     ));
88         else {
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());
93                 else
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],
100                             var(aux[i]),
101                             var(parameters[i])
102                             ));
103             context.match(Expressions.tuple(Expressions.vars(aux)), new EVariable(row), false);
104             context.iterateMSet(row, new EVariable(table));
105         }
106     }
107     
108     @Override
109     public String toString() {
110         return name;
111     }
112 }