]> gerrit.simantics Code Review - simantics/platform.git/blob
42eb9530d3717401b427b78f7c951c99620f8675
[simantics/platform.git] /
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.if_;
5 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda;
6 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.let;
7 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.letRec;
8 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple;
9 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
10
11 import org.simantics.scl.compiler.common.names.Name;
12 import org.simantics.scl.compiler.common.names.Names;
13 import org.simantics.scl.compiler.elaboration.expressions.EApply;
14 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
15 import org.simantics.scl.compiler.elaboration.expressions.Expression;
16 import org.simantics.scl.compiler.elaboration.expressions.Variable;
17 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
18 import org.simantics.scl.compiler.types.TVar;
19 import org.simantics.scl.compiler.types.Type;
20 import org.simantics.scl.compiler.types.Types;
21
22 public class TransitiveClosureRelation extends AbstractRelation implements CompositeRelation {
23
24     SCLRelation baseRelation;
25     
26     public TransitiveClosureRelation(SCLRelation baseRelation) {
27         this.baseRelation = baseRelation;
28     }
29
30     @Override
31     public TVar[] getTypeVariables() {
32         return baseRelation.getTypeVariables();
33     }
34
35     @Override
36     public Type[] getParameterTypes() {
37         return baseRelation.getParameterTypes();
38     }
39     
40     @Override
41     public double getSelectivity(int boundVariabes) {
42         return baseRelation.getSelectivity(boundVariabes)*5.0;
43     }
44     
45     @Override
46     public int getRequiredVariablesMask() {
47         return baseRelation.getRequiredVariablesMask();
48     }
49
50     @Override
51     public void generate(long location,
52             QueryCompilationContext context,
53             Type[] typeParameters, Variable[] parameters, int boundVariables) {
54         Variable bound, solved;
55         if(boundVariables == (1<<(parameters.length-1))-1) {
56             bound = parameters[0];
57             solved = parameters[parameters.length-1];
58         }
59         else if(boundVariables == (1<<(parameters.length))-2) {
60             bound = parameters[parameters.length-1];
61             solved = parameters[0];
62         }
63         else //if(boundVariables == 3 || boundVariables == 0)
64             throw new UnsupportedOperationException("boundVariables = " + boundVariables);
65         
66         Type type = baseRelation.getParameterTypes()[0];
67         if(typeParameters.length > 0)
68             type = type.replace(getTypeVariables(), typeParameters);
69
70         Expression continuation = context.getContinuation();
71         System.out.println("continuation = " + continuation + " :: " + continuation.getType());
72         Variable set = new Variable("set", Types.apply(Types.con("MSet", "T"), type));
73         Variable f = new Variable("f", Types.functionE(type, Types.PROC, continuation.getType()));
74         Variable innerSolved = new Variable("tcTemp", solved.getType());
75         System.out.println("set :: " + set.getType());
76         System.out.println("f :: " + f.getType());
77         System.out.println("tcTemp :: " + innerSolved.getType());
78         
79         QueryCompilationContext newContext = context.createSubcontext(new EApply(
80                 new EVariable(f), new EVariable(innerSolved)
81                 ));
82         Variable[] innerParameters = new Variable[parameters.length];
83         if(boundVariables == (1<<(parameters.length-1))-1) {
84             innerParameters[0] = solved;
85             innerParameters[parameters.length-1] = innerSolved;
86         }
87         else {
88             innerParameters[0] = innerSolved;
89             innerParameters[parameters.length-1] = solved;
90         }
91         for(int i=1;i<parameters.length-1;++i)
92             innerParameters[i] = parameters[i];
93         baseRelation.generate(location,
94                 newContext,
95                 typeParameters,
96                 innerParameters, boundVariables);
97         
98         continuation = context.disjunction(continuation, newContext.getContinuation());
99         continuation = if_(apply(context.getCompilationContext(), Types.PROC, Names.MSet_add, type,
100                 var(set), var(solved)),
101                 continuation,
102                 context.failure());
103         continuation = lambda(Types.PROC, solved, continuation);
104         continuation = letRec(f, continuation, apply(var(f), var(bound)));
105         continuation = let(set, 
106                 apply(context.getCompilationContext(), Types.PROC, Names.MSet_create, type, tuple()), 
107                 continuation);
108         context.setContinuation(continuation);
109         
110         // TODO Auto-generated method stub
111         // base :: (a -> <Proc> ()) -> a -> <Proc> ()
112         // initial :: a
113         // cont :: a -> <Proc> ()
114         /* s = MSet.create ()
115          * f cur = if MSet.add s cur
116          *         then do
117          *             cont cur
118          *             base f cur
119          *         else ()
120          * f cur = MSet.add s cur && (cont cur || base f cur)
121          * f cur = if MSet.add s cur
122          *         then match cont cur with
123          *             result @ (Just _) -> result
124          *             _ -> base f cur
125          *         else Nothing
126          */
127         
128         /* let s = MSet.new ()
129                f = \r -> if MSet.add s r
130                          then do
131                              g r
132                              rel 
133                          else ()
134            in  f init 
135          */
136     }
137
138     @Override
139     public SCLRelation[] getSubrelations() {
140         return new SCLRelation[] { baseRelation };
141     }
142
143 }