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