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