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