1 package org.simantics.scl.compiler.elaboration.chr;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
5 import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
6 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
7 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
8 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
9 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
10 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame;
11 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
12 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
13 import org.simantics.scl.compiler.elaboration.expressions.Expression;
14 import org.simantics.scl.compiler.elaboration.expressions.Variable;
15 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
16 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
17 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
18 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
19 import org.simantics.scl.compiler.errors.Locations;
20 import org.simantics.scl.compiler.internal.parsing.Symbol;
21 import org.simantics.scl.compiler.types.TVar;
22 import org.simantics.scl.compiler.types.Type;
23 import org.simantics.scl.compiler.types.Types;
24 import org.simantics.scl.compiler.types.kinds.Kinds;
26 import gnu.trove.map.hash.TObjectIntHashMap;
27 import gnu.trove.set.hash.THashSet;
28 import gnu.trove.set.hash.TIntHashSet;
30 public class CHRLiteral extends Symbol {
32 public CHRRelation relation;
33 public Type[] typeParameters;
34 public Expression[] parameters;
35 public FieldAssignment[] fields; // optional
36 public Expression[] typeConstraintEvidenceParameters;
37 public boolean killAfterMatch;
38 public boolean negated;
39 public boolean passive = true;
41 public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
42 this.location = location;
43 this.relation = relation;
44 this.parameters = parameters;
45 this.killAfterMatch = remove;
46 this.negated = negated;
49 public void resolve(TranslationContext context) {
50 if(relation == SpecialCHRRelation.ASSIGN) {
51 parameters[1] = parameters[1].resolve(context);
52 parameters[0] = parameters[0].resolveAsPattern(context);
55 if(parameters != null) {
56 for(int i=0;i<parameters.length;++i)
57 parameters[i] = parameters[i].resolve(context);
59 if(relation instanceof UnresolvedCHRRelation) {
60 UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;
61 CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);
62 if(constraint != null) {
63 relation = constraint;
67 SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);
68 if(sclRelation != null)
69 relation = new ExternalCHRRelation(sclRelation);
71 if(unresolved.name.contains(".")) {
72 context.getErrorLog().log(unresolved.location, "Couldn't resolve relation " + unresolved.name + ".");
75 if(parameters == null) {
76 context.getErrorLog().log(location, "Relation must be declared if record syntax is used.");
79 Type[] parameterTypes = new Type[parameters.length];
80 for(int i=0;i<parameterTypes.length;++i)
81 parameterTypes[i] = Types.metaVar(Kinds.STAR);
82 constraint = new CHRConstraint(location, unresolved.name, parameterTypes);
83 constraint.implicitlyDeclared = true;
84 context.newCHRConstraint(constraint.name, constraint);
85 relation = constraint;
87 //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");
91 if(parameters == null && fields != null) {
92 String[] fieldNames = relation.getFieldNames();
93 if(fieldNames == null) {
94 context.getErrorLog().log(location, "Relation " + relation + " does not define field names.");
97 parameters = ERecord.translateFieldsToFunctionParameters(context, fields, fieldNames);
98 if(parameters == null)
100 for(int i=0;i<parameters.length;++i) {
101 Expression parameter = parameters[i];
102 if(parameter == null) {
103 ExistentialFrame frame = context.getCurrentExistentialFrame();
104 if(frame == null || frame.disallowNewExistentials)
105 context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
107 parameters[i] = frame.createBlank(location);
110 parameters[i] = parameters[i].resolve(context);
116 public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
117 for(Expression parameter : parameters)
118 parameter.collectRefs(allRefs, refs);
119 if(typeConstraintEvidenceParameters != null)
120 for(Expression parameter : typeConstraintEvidenceParameters)
121 parameter.collectRefs(allRefs, refs);
124 public void checkType(TypingContext context) {
125 if(relation == SpecialCHRRelation.EXECUTE) {
126 if(parameters.length != 1)
127 throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");
128 parameters[0] = parameters[0].checkIgnoredType(context);
129 typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
131 else if(relation == SpecialCHRRelation.ASSIGN) {
132 parameters[1] = parameters[1].inferType(context);
133 parameters[0] = parameters[0].checkTypeAsPattern(context, parameters[1].getType());
134 typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
137 TVar[] typeVariables = relation.getTypeVariables();
138 typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];
139 for(int i=0;i<typeVariables.length;++i)
140 typeParameters[i] = Types.metaVar(typeVariables[i].getKind());
141 Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);
142 if(parameterTypes.length != parameters.length)
143 context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");
145 for(int i=0;i<parameters.length;++i)
146 parameters[i] = parameters[i].checkType(context, parameterTypes[i]);
148 typeConstraintEvidenceParameters = context.addConstraints(Types.replace(relation.getTypeConstraints(), typeVariables, typeParameters));
152 public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
153 for(Expression parameter : parameters)
154 parameter.collectVars(allVars, vars);
155 if(typeConstraintEvidenceParameters != null)
156 for(Expression parameter : typeConstraintEvidenceParameters)
157 parameter.collectVars(allVars, vars);
160 public void forVariables(VariableProcedure procedure) {
161 for(Expression parameter : parameters)
162 parameter.forVariables(procedure);
163 if(typeConstraintEvidenceParameters != null)
164 for(Expression parameter : typeConstraintEvidenceParameters)
165 parameter.forVariables(procedure);
168 public void collectFreeVariables(THashSet<Variable> vars) {
169 if(relation == SpecialCHRRelation.ASSIGN) {
170 parameters[1].collectFreeVariables(vars);
173 for(Expression parameter : parameters)
174 parameter.collectFreeVariables(vars);
175 if(typeConstraintEvidenceParameters != null)
176 for(Expression parameter : typeConstraintEvidenceParameters)
177 parameter.collectFreeVariables(vars);
181 public void setLocationDeep(long loc) {
182 if(location == Locations.NO_LOCATION) {
184 for(Expression parameter : parameters)
185 parameter.setLocationDeep(loc);
189 public void simplify(SimplificationContext context) {
190 for(int i=0;i<parameters.length;++i)
191 parameters[i] = parameters[i].simplify(context);
192 if(typeConstraintEvidenceParameters != null)
193 for(int i=0;i<typeConstraintEvidenceParameters.length;++i)
194 typeConstraintEvidenceParameters[i] = typeConstraintEvidenceParameters[i].simplify(context);
197 public String toString() {
198 StringBuilder b = new StringBuilder();
199 ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
204 public void collectQueryEffects(THashSet<Type> effects) {
208 public void collectEnforceEffects(THashSet<Type> effects) {