1 package org.simantics.scl.compiler.elaboration.relations;
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;
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;
24 public class TransitiveClosureRelation extends AbstractRelation implements CompositeRelation {
26 SCLRelation baseRelation;
28 public TransitiveClosureRelation(SCLRelation baseRelation) {
29 this.baseRelation = baseRelation;
33 public TVar[] getTypeVariables() {
34 return baseRelation.getTypeVariables();
38 public Type[] getParameterTypes() {
39 return baseRelation.getParameterTypes();
43 public double getSelectivity(int boundVariabes) {
44 return baseRelation.getSelectivity(boundVariabes)*5.0;
48 public int getRequiredVariablesMask() {
49 return baseRelation.getRequiredVariablesMask();
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];
61 else if(boundVariables == (1<<(parameters.length))-2) {
62 bound = parameters[parameters.length-1];
63 solved = parameters[0];
65 else //if(boundVariables == 3 || boundVariables == 0)
66 throw new UnsupportedOperationException("boundVariables = " + boundVariables);
68 Type type = baseRelation.getParameterTypes()[0];
69 if(typeParameters.length > 0)
70 type = type.replace(getTypeVariables(), typeParameters);
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());
81 QueryCompilationContext newContext = context.createSubcontext(new EApply(
82 new EVariable(f), new EVariable(innerSolved)
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;
90 innerParameters[0] = innerSolved;
91 innerParameters[parameters.length-1] = solved;
93 for(int i=1;i<parameters.length-1;++i)
94 innerParameters[i] = parameters[i];
95 baseRelation.generate(location,
98 innerParameters, boundVariables);
100 continuation = context.disjunction(continuation, newContext.getContinuation());
101 continuation = if_(apply(context, Types.PROC, Name.create("MSet", "add"), type,
102 var(set), var(solved)),
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()),
110 context.setContinuation(continuation);
112 // TODO Auto-generated method stub
113 // base :: (a -> <Proc> ()) -> a -> <Proc> ()
115 // cont :: a -> <Proc> ()
116 /* s = MSet.create ()
117 * f cur = if MSet.add s cur
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
130 /* let s = MSet.new ()
131 f = \r -> if MSet.add s r
141 public SCLRelation[] getSubrelations() {
142 return new SCLRelation[] { baseRelation };