]> gerrit.simantics Code Review - simantics/platform.git/blob
900c9627bc1fbbd2b98acedff7d44c45364de4c3
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.relations;
2
3 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;
4
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;
16
17 public class LocalRelation extends AbstractRelation {
18     String name;
19     Type[] parameterTypes;
20     public Variable table;
21     
22     public LocalRelation(String name, int arity) {
23         this.name = name;
24         this.parameterTypes = new Type[arity];
25         for(int i=0;i<arity;++i)
26             parameterTypes[i] = Types.metaVar(Kinds.STAR);
27         createTable();
28     }
29     
30     public LocalRelation(String name, Type[] parameterTypes) {
31         this.name = name;
32         this.parameterTypes = parameterTypes;
33         createTable();
34     }
35     
36     private void createTable() {
37         this.table = newVar("table" + name, 
38                 Types.apply(ERuleset.MSet, Types.tuple(parameterTypes)));
39     }
40     
41     public int getArity() {
42         return parameterTypes.length;
43     }
44
45     public String getName() {
46         return name;
47     }
48     
49     @Override
50     public TVar[] getTypeVariables() {
51         return TVar.EMPTY_ARRAY;
52     }
53
54     @Override
55     public Type[] getParameterTypes() {
56         return parameterTypes;
57     }
58     
59     @Override
60     public double getSelectivity(int boundVariabes) {
61         double s = 0.95;
62         for(int i=0;i<parameterTypes.length;++i,boundVariabes>>=1)
63             if( (boundVariabes&1) == 0 )
64                 s *= 10.0;
65         return s;
66     }
67     
68     @Override
69     public int getRequiredVariablesMask() {
70         return 0;
71     }
72     
73     private static final Name MSet_contains = Name.create("MSet", "contains"); 
74     private static final Name EQ = Name.create("Prelude", "==");
75     @Override
76     public void generate(long location,
77             QueryCompilationContext context,
78             Type[] typeParameters, Variable[] parameters, int boundVariables) {
79         if(table == null)
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),
84                     var(table),
85                     tuple(vars(parameters))
86                     ));
87         else {
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());
92                 else
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])),
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 }