diff options
author | OszkarSemerath <oszka@152.66.252.189> | 2017-06-10 19:05:05 +0200 |
---|---|---|
committer | OszkarSemerath <oszka@152.66.252.189> | 2017-06-10 19:05:05 +0200 |
commit | 60f01f46ba232ed6416054f0a6115cb2a9b70b4e (patch) | |
tree | 5edf8aeb07abc51f3fec63bbd15c926e1de09552 /Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend | |
parent | Initial commit, migrating from SVN (diff) | |
download | VIATRA-Generator-60f01f46ba232ed6416054f0a6115cb2a9b70b4e.tar.gz VIATRA-Generator-60f01f46ba232ed6416054f0a6115cb2a9b70b4e.tar.zst VIATRA-Generator-60f01f46ba232ed6416054f0a6115cb2a9b70b4e.zip |
Migrating Additional projects
Diffstat (limited to 'Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend')
-rw-r--r-- | Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend | 563 |
1 files changed, 563 insertions, 0 deletions
diff --git a/Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend b/Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend new file mode 100644 index 00000000..ba1b9fd6 --- /dev/null +++ b/Framework/hu.bme.mit.inf.dslreasoner.logic.model/src/hu/bme/mit/inf/dslreasoner/logic/model/builder/LogicProblemBuilder.xtend | |||
@@ -0,0 +1,563 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.logic.model.builder | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Assertion | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Constant | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | ||
8 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Function | ||
9 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference | ||
10 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory | ||
11 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.QuantifiedExpression | ||
12 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference | ||
13 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation | ||
14 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition | ||
15 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.SymbolicValue | ||
16 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Term | ||
17 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TermDescription | ||
18 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
19 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition | ||
20 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDescriptor | ||
21 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference | ||
22 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Variable | ||
23 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.ContainmentHierarchy | ||
24 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
25 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemFactory | ||
26 | import hu.bme.mit.inf.dslreasoner.util.LogicProblemBuilder_AdvancedConstructs | ||
27 | import java.math.BigDecimal | ||
28 | import java.util.ArrayList | ||
29 | import java.util.Collections | ||
30 | import java.util.LinkedList | ||
31 | import java.util.List | ||
32 | import java.util.Map | ||
33 | import org.eclipse.emf.ecore.EObject | ||
34 | import org.eclipse.emf.ecore.util.EcoreUtil | ||
35 | import org.eclipse.xtend.lib.annotations.Data | ||
36 | import org.eclipse.xtext.xbase.lib.Functions.Function1 | ||
37 | |||
38 | @Data class FunctionDescription { | ||
39 | Iterable<TypeReference> parameters | ||
40 | TypeReference range | ||
41 | } | ||
42 | |||
43 | class LogicProblemBuilderException extends Exception { | ||
44 | new(String reason) { | ||
45 | super(reason) | ||
46 | } | ||
47 | } | ||
48 | |||
49 | public class LogicProblemBuilder{ | ||
50 | val protected extension LogiclanguageFactory logicFactiory = LogiclanguageFactory.eINSTANCE | ||
51 | val protected extension LogicproblemFactory problemFactory = LogicproblemFactory.eINSTANCE | ||
52 | val protected advancedConstructs = new LogicProblemBuilder_AdvancedConstructs(this) | ||
53 | |||
54 | def public createProblem(){ createLogicProblem } | ||
55 | |||
56 | // Names | ||
57 | def protected String canonize(CharSequence name) { | ||
58 | if(name == null) return "" | ||
59 | val result = name.toString.split("\\s+"); | ||
60 | if(result.size == 1) { | ||
61 | val element = result.get(0); | ||
62 | if(element == "bool" || | ||
63 | element == "int" || | ||
64 | element == "real") throw new LogicProblemBuilderException('''Reserved keyword "«element»"!''') | ||
65 | else return result.join(' ') | ||
66 | } | ||
67 | else return result.join(' ') | ||
68 | } | ||
69 | def protected String generateUniqueName(Iterable<String> previous, Function1<Integer,String> namer) { | ||
70 | var int i = 0 | ||
71 | var generateNew = false; | ||
72 | var String finalName; | ||
73 | do { | ||
74 | i = i+1; | ||
75 | val nameCandidate = namer.apply(i) | ||
76 | finalName = nameCandidate | ||
77 | generateNew = previous.exists[equals(nameCandidate)] | ||
78 | } | ||
79 | while(generateNew) | ||
80 | return finalName | ||
81 | } | ||
82 | |||
83 | // Type builders | ||
84 | def public Element(CharSequence elementName) { return createDefinedElement => [x|x.name = elementName.canonize] } | ||
85 | def public Element() { return createDefinedElement } | ||
86 | def public TypeDeclaration(CharSequence name, boolean isAbstract) { TypeDeclaration => [x | x.name = name.canonize x.isAbstract = isAbstract] } | ||
87 | def public TypeDeclaration() { createTypeDeclaration } | ||
88 | def public TypeDefinition(CharSequence name, boolean isAbstract, DefinedElement... elements) { TypeDefinition(name, isAbstract, elements as Iterable<DefinedElement>) } | ||
89 | def public TypeDefinition(CharSequence name, boolean isAbstract, Iterable<DefinedElement> elements) { createTypeDefinition => [x | x.name = name.canonize x.isAbstract = isAbstract x.elements += elements ] } | ||
90 | |||
91 | def public Supertype(Type subtype, Type supertype) { | ||
92 | subtype.supertypes+=supertype | ||
93 | } | ||
94 | def public SetSupertype(Type subtype, Type supertype, boolean value) { | ||
95 | if(value) subtype.supertypes+=supertype | ||
96 | else subtype.subtypes-=supertype | ||
97 | } | ||
98 | |||
99 | // Type add | ||
100 | def public add(LogicProblem problem, Type type) { | ||
101 | problem.nameIfAnonymType(type) | ||
102 | problem.types+=type | ||
103 | if(type instanceof TypeDefinition) { | ||
104 | problem.elements+=type.elements | ||
105 | } | ||
106 | return type | ||
107 | } | ||
108 | def protected dispatch nameIfAnonymType(LogicProblem problem, Type typeDeclaration) { | ||
109 | if(typeDeclaration.name.nullOrEmpty) | ||
110 | typeDeclaration.name = problem.types.map[it.name].generateUniqueName[i | '''type «i.toString»'''] | ||
111 | } | ||
112 | def protected dispatch nameIfAnonymType(LogicProblem problem, TypeDefinition typeDefinition) { | ||
113 | if(typeDefinition.name.nullOrEmpty) | ||
114 | typeDefinition.name = problem.types.map[it.name].generateUniqueName[i | '''type «i.toString»'''] | ||
115 | for(element : typeDefinition.elements) | ||
116 | if(element.name.nullOrEmpty) | ||
117 | element.name = typeDefinition.elements.map[it.name].generateUniqueName[i | '''type «i.toString»'''] | ||
118 | } | ||
119 | |||
120 | def public LogicBool() { createBoolTypeReference } | ||
121 | def public LogicInt() { createIntTypeReference } | ||
122 | def public LogicReal() { createRealTypeReference } | ||
123 | def toTypeReference(TypeDescriptor descriptor) { | ||
124 | if(descriptor instanceof TypeReference) { return EcoreUtil.copy(descriptor); } | ||
125 | else if(descriptor instanceof Type) { return createComplexTypeReference => [referred = descriptor]} | ||
126 | else throw new UnsupportedOperationException("Unsupported type descriptor: " + descriptor.class) | ||
127 | } | ||
128 | |||
129 | // Variables | ||
130 | def public createVar(CharSequence name, TypeDescriptor range) { | ||
131 | return createVariable => [it.name = name.canonize it.range = range.toTypeReference] | ||
132 | } | ||
133 | |||
134 | // Functions | ||
135 | def public FunctionDescription ->(TypeDescriptor parameter, TypeDescriptor range) { return #[parameter] -> range } | ||
136 | def public FunctionDescription ->(Iterable<? extends TypeDescriptor> parameters, TypeDescriptor range) { return new FunctionDescription(parameters.map[toTypeReference], range.toTypeReference); } | ||
137 | def public FunctionDeclaration(CharSequence name, FunctionDescription functionDescription) { FunctionDeclaration(name,functionDescription.range, functionDescription.parameters) } | ||
138 | def public FunctionDeclaration(FunctionDescription functionDescription) { FunctionDeclaration(functionDescription.range, functionDescription.parameters) } | ||
139 | def public FunctionDeclaration(CharSequence name, TypeDescriptor range, TypeDescriptor... parameters) { FunctionDeclaration(name, range, parameters as Iterable<? extends TypeReference>) } | ||
140 | def public FunctionDeclaration(TypeDescriptor range, TypeDescriptor... parameters) { FunctionDeclaration(range, parameters as Iterable<? extends TypeReference>) } | ||
141 | def public FunctionDeclaration(CharSequence name, TypeDescriptor range, Iterable<? extends TypeDescriptor> parameters) { return FunctionDeclaration(range,parameters) => [x|x.name = name.canonize] } | ||
142 | def public FunctionDeclaration(TypeDescriptor range, Iterable<? extends TypeDescriptor> parameters) { | ||
143 | val function = createFunctionDeclaration | ||
144 | for(parameter : parameters) function.parameters+=parameter.toTypeReference | ||
145 | function.range = range.toTypeReference | ||
146 | return function | ||
147 | } | ||
148 | |||
149 | def public FunctionDefinition(CharSequence name, TypeDescriptor range, Function1<VariableContext, ? extends TermDescription> expression) { | ||
150 | val context = new VariableContext(this,logicFactiory) | ||
151 | val definition = expression.apply(context) | ||
152 | return FunctionDefinition(name,range,context.variables,definition); | ||
153 | } | ||
154 | def public FunctionDefinition(CharSequence name, TypeDescriptor range, Iterable<Variable> variables, TermDescription definition) { | ||
155 | return createFunctionDefinition => [ | ||
156 | it.name = name.canonize | ||
157 | it.parameters += variables.map[it.range.toTypeReference] | ||
158 | it.variable += variables | ||
159 | it.range = range.toTypeReference | ||
160 | it.value = definition.toTerm | ||
161 | ] | ||
162 | } | ||
163 | def public FunctionDefinition(CharSequence name, TypeDescriptor range, Iterable<TypeDescriptor> parameters, Map<List<Term>,Term> parametersToValue) { | ||
164 | return FunctionDefinition(name,range,parameters,parametersToValue,null) | ||
165 | } | ||
166 | def public FunctionDefinition(CharSequence name, TypeDescriptor range, Iterable<TypeDescriptor> parameters, Map<List<Term>,Term> parametersToValue, Term defaultValue) { | ||
167 | val parameterList = parameters.toList; | ||
168 | val variableList = (1..parameterList.size).map[index | '''param «index»'''.createVar(parameterList.get(index-1))].toList | ||
169 | return FunctionDefinition(name,range,variableList,advancedConstructs.FunctionDefinitionBody(variableList,parametersToValue,defaultValue)) | ||
170 | } | ||
171 | |||
172 | // Add function to a problem | ||
173 | def public add(LogicProblem input, Function function) { | ||
174 | input.nameIfAnonymFunction(function) | ||
175 | input.checkFunction(function) | ||
176 | input.functions += function | ||
177 | return function | ||
178 | } | ||
179 | def public add(LogicProblem input, FunctionDescription functionDescription) { input.add(FunctionDeclaration(functionDescription)) } | ||
180 | def protected nameIfAnonymFunction(LogicProblem problem, Function functionDeclaration) { | ||
181 | if(functionDeclaration.name.nullOrEmpty) { | ||
182 | functionDeclaration.name = problem.functions.map[it.name].generateUniqueName[i | "function"+i] | ||
183 | } | ||
184 | } | ||
185 | def protected checkFunction(LogicProblem problem, Function function) { | ||
186 | if(problem.functions.exists(x|x.name == function.name)) | ||
187 | throw new LogicProblemBuilderException('''Function with the following name is already defined: "«function.name»"!''') | ||
188 | for(ref : function.parameters.filter(typeof(ComplexTypeReference)).map[referred]) { | ||
189 | if(!problem.types.contains(ref)) | ||
190 | throw new LogicProblemBuilderException('''Type "«ref.name»" is not availabe in the logic problem!''') | ||
191 | } | ||
192 | val range = function.range | ||
193 | if(range instanceof ComplexTypeReference) { | ||
194 | if(!problem.types.contains(range.referred)) | ||
195 | throw new LogicProblemBuilderException('''Type "«range.referred.name»" is not availabe in the logic problem!''') | ||
196 | } | ||
197 | } | ||
198 | |||
199 | // Constants | ||
200 | def public ConstantDeclaration(CharSequence name, TypeDescriptor type) { ConstantDeclaration(type) => [it.name = name.canonize] } | ||
201 | def public ConstantDeclaration(TypeDescriptor type) { createConstantDeclaration => [it.type = type.toTypeReference] } | ||
202 | |||
203 | def public ConstantDefinition(CharSequence name, TypeDescriptor type, TermDescription value) { | ||
204 | createConstantDefinition => [it.name = name.canonize it.type = type.toTypeReference it.value = value.toTerm] | ||
205 | } | ||
206 | |||
207 | // Add constant to a problem | ||
208 | def public add(LogicProblem problem, Constant constant) { | ||
209 | problem.nameIfAnonymConstant(constant); | ||
210 | problem.checkConstant(constant) | ||
211 | problem.constants += constant | ||
212 | return constant | ||
213 | } | ||
214 | def protected nameIfAnonymConstant(LogicProblem problem, Constant constant) { | ||
215 | if(constant.name.nullOrEmpty) { | ||
216 | constant.name = problem.constants.map[it.name].generateUniqueName[i | "constant"+i] | ||
217 | } | ||
218 | } | ||
219 | def protected checkConstant(LogicProblem problem, Constant constant) { | ||
220 | if(problem.constants.exists(x|x.name == constant.name)) | ||
221 | throw new LogicProblemBuilderException('''Constant with the following name is already defined: "«constant.name»"!''') | ||
222 | if((constant.type instanceof ComplexTypeReference) && ! (problem.types.contains((constant.type as ComplexTypeReference).referred))) | ||
223 | throw new LogicProblemBuilderException('''Type "«(constant.type as ComplexTypeReference).referred.name»" is not availabe in the logic problem!''') | ||
224 | } | ||
225 | |||
226 | // Relations | ||
227 | def public RelationDeclaration(CharSequence name, TypeDescriptor... parameters) { return RelationDeclaration(name, parameters as Iterable<? extends TypeReference>) } | ||
228 | def public RelationDeclaration(CharSequence name, Iterable<? extends TypeDescriptor> parameters) { return RelationDeclaration(parameters) => [x|x.name = name.canonize] } | ||
229 | def public RelationDeclaration(TypeDescriptor... parameters) { RelationDeclaration( parameters as Iterable<? extends TypeReference>) } | ||
230 | def public RelationDeclaration(Iterable<? extends TypeDescriptor> parameters) { | ||
231 | val relation = createRelationDeclaration | ||
232 | for(parameter : parameters) { | ||
233 | relation.parameters+=parameter.toTypeReference | ||
234 | } | ||
235 | return relation | ||
236 | } | ||
237 | |||
238 | def public RelationDefinition(CharSequence name, Function1<VariableContext, ? extends TermDescription> expression) { | ||
239 | val context = new VariableContext(this,logicFactiory); | ||
240 | val definition = expression.apply(context); | ||
241 | return RelationDefinition(name,context.variables,definition) | ||
242 | } | ||
243 | def public RelationDefinition(CharSequence name, Iterable<Variable> variables, TermDescription definition) { | ||
244 | return createRelationDefinition => [ | ||
245 | it.name = name.canonize | ||
246 | it.parameters += variables.map[it.range.toTypeReference] | ||
247 | it.variables += variables | ||
248 | it.value = definition?.toTerm | ||
249 | ] | ||
250 | } | ||
251 | def public RelationDefinition(CharSequence name, Iterable<? extends TypeDescriptor> parameters, Iterable<? extends List<? extends TermDescription>> possibleValues) { | ||
252 | val res = createRelationDefinition => [it.name = name.canonize] | ||
253 | val variableMap = new ArrayList(parameters.size) | ||
254 | var index = 0 | ||
255 | for(parameter : parameters) { | ||
256 | val actualIndex = index | ||
257 | val newVar = createVariable=>[it.name ='''var «actualIndex»'''.canonize it.range = parameter.toTypeReference] | ||
258 | variableMap.add(index,newVar) | ||
259 | res.variables+=newVar | ||
260 | res.parameters+=newVar.range | ||
261 | index+=1 | ||
262 | } | ||
263 | res.value = possibleValues.map[possibleValue |(0..<parameters.size).map[i| variableMap.get(i) == possibleValue.get(i).toTerm].And].Or | ||
264 | return res | ||
265 | } | ||
266 | |||
267 | // Add Relation to a problem | ||
268 | def public add(LogicProblem input, Relation relation) { | ||
269 | input.nameIfAnonymRelation(relation) | ||
270 | input.checkRelation(relation) | ||
271 | input.relations+=relation | ||
272 | //println('''«relation.name» - [«relation.parameters»]''') | ||
273 | return relation | ||
274 | } | ||
275 | |||
276 | def protected nameIfAnonymRelation(LogicProblem problem, Relation relation) { | ||
277 | if(relation.name.nullOrEmpty) { | ||
278 | relation.name = problem.relations.map[it.name].generateUniqueName[i | "relation"+i] | ||
279 | } | ||
280 | } | ||
281 | def protected checkRelation(LogicProblem problem, Relation relation) { | ||
282 | if(problem.relations.exists(x|x.name == relation.name)) | ||
283 | throw new LogicProblemBuilderException('''Relation with the following name is already defined: "«relation.name»"!''') | ||
284 | for(ref : relation.parameters.filter(typeof(ComplexTypeReference)).map[referred]) { | ||
285 | if(!problem.types.contains(ref)) | ||
286 | throw new LogicProblemBuilderException('''Type "«ref.name»" is not availabe in the logic problem!''') | ||
287 | } | ||
288 | if(relation instanceof RelationDefinition) { | ||
289 | checkDefinition(relation) | ||
290 | } | ||
291 | } | ||
292 | |||
293 | // Assertion | ||
294 | def public Assertion(TermDescription term) { | ||
295 | val result = term.toTerm | ||
296 | result.nameAnonymVariables(Collections.EMPTY_LIST) | ||
297 | createAssertion => [it.value = result] | ||
298 | } | ||
299 | def public Assertion(CharSequence name, TermDescription term) { | ||
300 | val result = term.toTerm | ||
301 | result.nameAnonymVariables(Collections.EMPTY_LIST) | ||
302 | createAssertion => [it.value = result it.name=name.canonize] | ||
303 | } | ||
304 | def public add(LogicProblem problem, Assertion assertion) { | ||
305 | if(assertion.name.nullOrEmpty) { | ||
306 | val name = problem.assertions.map[name].generateUniqueName["assertion"+it] | ||
307 | assertion.name=name | ||
308 | } | ||
309 | checkAssertion(assertion) | ||
310 | problem.assertions+=assertion | ||
311 | return assertion | ||
312 | } | ||
313 | |||
314 | def public add(LogicProblem problem, TermDescription term) { | ||
315 | problem.add(Assertion(term)) | ||
316 | } | ||
317 | |||
318 | |||
319 | def checkAssertion(Assertion assertion) { | ||
320 | for(value : assertion.eAllContents.filter(SymbolicValue).toIterable) { | ||
321 | var referred = value.symbolicReference | ||
322 | if(referred instanceof Variable) { | ||
323 | if(!value.hasDeclaredVariable(referred)){ | ||
324 | throw new LogicProblemBuilderException('''Variable "«referred.name»" is not availabe in the logic problem!''') | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | |||
330 | def public checkDefinition(EObject definition) { | ||
331 | /*for(value : definition.eAllContents.filter(SymbolicValue).toIterable) { | ||
332 | var referred = value.symbolicReference | ||
333 | if(referred instanceof Variable) { | ||
334 | if(!value.hasDeclaredVariable(referred)){ | ||
335 | throw new LogicProblemBuilderException('''Variable "«referred.name»" is not availabe in the logic problem!''') | ||
336 | } | ||
337 | } | ||
338 | }*/ | ||
339 | } | ||
340 | |||
341 | // Containment | ||
342 | def public ContainmentHierarchy( | ||
343 | Iterable<? extends Type> typesInHierarchy, | ||
344 | Iterable<? extends Function> containmentFunctions, | ||
345 | Iterable<? extends Relation> containmentRelations, | ||
346 | Constant rootConstant | ||
347 | ) { | ||
348 | val result = createContainmentHierarchy => [ | ||
349 | it.typesOrderedInHierarchy += typesInHierarchy | ||
350 | it.containmentFunctions += containmentFunctions | ||
351 | it.containmentRelations += containmentRelations | ||
352 | it.rootConstant = rootConstant | ||
353 | ] | ||
354 | return result | ||
355 | } | ||
356 | def public add(LogicProblem problem, ContainmentHierarchy hierarchy) { | ||
357 | problem.containmentHierarchies+=hierarchy | ||
358 | return hierarchy | ||
359 | } | ||
360 | |||
361 | // Terms | ||
362 | |||
363 | private dispatch def boolean hasDeclaredVariable(QuantifiedExpression term, Variable variable) { | ||
364 | return term.quantifiedVariables.contains(variable) || ((term.eContainer instanceof Term) && (term.eContainer as Term).hasDeclaredVariable(variable)) | ||
365 | } | ||
366 | private dispatch def boolean hasDeclaredVariable(Term term, Variable variable) { | ||
367 | return (term.eContainer instanceof Term) && (term.eContainer as Term).hasDeclaredVariable(variable) | ||
368 | } | ||
369 | private dispatch def boolean hasDeclaredVariable(RelationDefinition relation, Variable variable) { | ||
370 | relation.variables.contains(variable) | ||
371 | } | ||
372 | private dispatch def boolean hasDeclaredVariable(Void term, Variable variable) { | ||
373 | return false | ||
374 | } | ||
375 | |||
376 | def protected void nameAnonymVariables(EObject termSegment, List<String> previousNames) { | ||
377 | if(termSegment instanceof QuantifiedExpression) { | ||
378 | val newNames = new LinkedList(previousNames) | ||
379 | for(variable : termSegment.quantifiedVariables) { | ||
380 | var String newName | ||
381 | if(variable.name.nullOrEmpty) { | ||
382 | newName = newNames.generateUniqueName[i | | ||
383 | var x = variable.range.variableAnonymName | ||
384 | x+="var"+i.toString | ||
385 | //println(x) | ||
386 | return x | ||
387 | ] | ||
388 | variable.name = newName | ||
389 | } | ||
390 | else newName = variable.name | ||
391 | newNames+= newName | ||
392 | } | ||
393 | termSegment.expression.nameAnonymVariables(newNames) | ||
394 | } | ||
395 | else { | ||
396 | for(subTerm : termSegment.eContents) { | ||
397 | subTerm.nameAnonymVariables(previousNames) | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | def protected dispatch String variableAnonymName(BoolTypeReference ref) { "bool" } | ||
402 | def protected dispatch String variableAnonymName(IntTypeReference ref) { "int" } | ||
403 | def protected dispatch String variableAnonymName(RealTypeReference ref) { "real" } | ||
404 | def protected dispatch String variableAnonymName(ComplexTypeReference ref) { ref.referred.name.toLowerCase } | ||
405 | |||
406 | def protected allSubterms(Term term) { | ||
407 | val content = term.eAllContents | ||
408 | val result = new ArrayList<EObject>(content.size+1) | ||
409 | result+=term | ||
410 | result+=content.toIterable | ||
411 | return result; | ||
412 | } | ||
413 | |||
414 | def public Term toTerm(TermDescription term) { | ||
415 | if(term instanceof Term) return term | ||
416 | else if (term instanceof Variable) return createSymbolicValue => [symbolicReference = term] | ||
417 | else if (term instanceof Constant) return term.call() | ||
418 | else if (term instanceof DefinedElement) return createSymbolicValue => [symbolicReference = term] | ||
419 | else throw new UnsupportedOperationException("Can not create reference for symbolic declaration " + term.class.name) | ||
420 | } | ||
421 | |||
422 | def public !(TermDescription term) { Not(term) } | ||
423 | def public Not(TermDescription term) { createNot => [operand = term.toTerm] } | ||
424 | |||
425 | def public &&(TermDescription a, TermDescription b) { And(a,b) } | ||
426 | def public And(TermDescription... terms) { return And(terms as Iterable<? extends TermDescription>) } | ||
427 | def public And(Iterable<? extends TermDescription> terms) { createAnd => [operands += terms.map[toTerm]] } | ||
428 | |||
429 | def public ||(TermDescription a, TermDescription b) { Or(a,b) } | ||
430 | def public Or(TermDescription... terms) { Or(terms as Iterable<? extends TermDescription>) } | ||
431 | def public Or(Iterable<? extends TermDescription> terms) { createOr => [operands += terms.map[toTerm]] } | ||
432 | |||
433 | def public =>(TermDescription a, TermDescription b) { Impl(a,b) } | ||
434 | def public Impl(TermDescription a, TermDescription b) { createImpl => [leftOperand = a.toTerm rightOperand = b.toTerm] } | ||
435 | |||
436 | def public <=>(TermDescription a, TermDescription b) { Iff(a,b)} | ||
437 | def public Iff(TermDescription a, TermDescription b) { createIff =>[leftOperand=a.toTerm rightOperand=b.toTerm] } | ||
438 | |||
439 | def public ITE(TermDescription condition, TermDescription ifTrue, TermDescription ifFalse) { | ||
440 | createIfThenElse => [it.condition = condition.toTerm it.ifTrue = ifTrue.toTerm it.ifFalse = ifFalse.toTerm] | ||
441 | } | ||
442 | |||
443 | def public >(TermDescription left, TermDescription right) { MoreThan(left,right)} | ||
444 | def public MoreThan(TermDescription left, TermDescription right) { createMoreThan => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
445 | |||
446 | def public <(TermDescription left, TermDescription right) { LessThan(left,right)} | ||
447 | def public LessThan(TermDescription left, TermDescription right) { createLessThan => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
448 | |||
449 | def public <=(TermDescription left, TermDescription right) { LessOrEqual(left,right) } | ||
450 | def public LessOrEqual(TermDescription left, TermDescription right) { createLessOrEqualThan => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
451 | |||
452 | def public >=(TermDescription left, TermDescription right) { MoreOrEqual(left,right) } | ||
453 | def public MoreOrEqual(TermDescription left, TermDescription right) { createMoreOrEqualThan => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
454 | |||
455 | def public ==(TermDescription left, TermDescription right) {Equals(left,right)} | ||
456 | def public Equals(TermDescription left, TermDescription right) { createEquals => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
457 | |||
458 | def public !=(TermDescription left, TermDescription right) { Distinct(left,right) } | ||
459 | def public Distinct(TermDescription... terms) { return Distinct(terms as Iterable<? extends TermDescription>) } | ||
460 | def public Distinct(Iterable<? extends TermDescription> terms) { createDistinct => [operands += terms.map[toTerm]] } | ||
461 | |||
462 | def public +(TermDescription left, TermDescription right) { Plus(left,right) } | ||
463 | def public Plus(TermDescription left, TermDescription right) { createPlus => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
464 | |||
465 | def public -(TermDescription left, TermDescription right) { Minus(left,right) } | ||
466 | def public Minus(TermDescription left, TermDescription right) { createMinus => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
467 | |||
468 | def public *(TermDescription left, TermDescription right) { Multiply(left,right) } | ||
469 | def public Multiply(TermDescription left, TermDescription right) { createMultiply => [leftOperand=left.toTerm rightOperand=right.toTerm] } | ||
470 | |||
471 | def public /(TermDescription left, TermDescription right) { Divide(left,right) } | ||
472 | def public Divide(TermDescription left, TermDescription right) { createDivison => [leftOperand = left.toTerm rightOperand = right.toTerm]} | ||
473 | |||
474 | def public %(TermDescription left, TermDescription right) { Modulo(left,right) } | ||
475 | def public Modulo(TermDescription left, TermDescription right) { createMod => [leftOperand = left.toTerm rightOperand = right.toTerm]} | ||
476 | |||
477 | def public asTerm(boolean value) { createBoolLiteral => [x|x.value = value] } | ||
478 | def public asTerm(int value) { createIntLiteral => [x|x.value = value] } | ||
479 | def public asTerm(double value) { createRealLiteral => [x|x.value = BigDecimal.valueOf(value)] } | ||
480 | |||
481 | def public InstanceOf(TermDescription term, TypeDescriptor type) { | ||
482 | createInstanceOf => [ | ||
483 | it.value = term.toTerm | ||
484 | it.range = type.toTypeReference | ||
485 | ] | ||
486 | } | ||
487 | |||
488 | // QuantifiedExpressions | ||
489 | |||
490 | def public Forall(Function1<VariableContext, ? extends TermDescription> expression) { | ||
491 | val context = new VariableContext(this,logicFactiory) | ||
492 | val term = expression.apply(context) | ||
493 | return createForall => [x| x.quantifiedVariables+=context.variables x.expression = term.toTerm] | ||
494 | } | ||
495 | def public Forall(TermDescription expression, Variable... variables) { | ||
496 | Forall(variables,expression) } | ||
497 | def public Forall(Iterable<? extends Variable> variables,TermDescription expression) { | ||
498 | val forallExpression = createForall | ||
499 | for(variable : variables) forallExpression.quantifiedVariables += variable | ||
500 | forallExpression.expression = expression.toTerm | ||
501 | return forallExpression | ||
502 | } | ||
503 | |||
504 | def public Exists(Function1<VariableContext, ? extends TermDescription> expression) { | ||
505 | val context = new VariableContext(this,logicFactiory) | ||
506 | val term = expression.apply(context) | ||
507 | return createExists => [x| x.quantifiedVariables+=context.variables x.expression = term.toTerm] | ||
508 | } | ||
509 | def public Exists(TermDescription expression, Variable... variables) { | ||
510 | Exists(variables,expression) } | ||
511 | def public Exists(Iterable<? extends Variable> variables, TermDescription expression) { | ||
512 | val existsExpression = createExists | ||
513 | for(variable : variables) existsExpression.quantifiedVariables += variable | ||
514 | existsExpression.expression = expression.toTerm | ||
515 | return existsExpression | ||
516 | } | ||
517 | |||
518 | // Function calls | ||
519 | def public call(Function function, TermDescription... substitutions) { | ||
520 | call(function, substitutions as Iterable<? extends TermDescription>) } | ||
521 | def public call(Function function, Iterable<? extends TermDescription> substitutions) { | ||
522 | val functionReference = createSymbolicValue | ||
523 | functionReference.symbolicReference=function | ||
524 | val List<TermDescription> l= new LinkedList() | ||
525 | l.addAll(substitutions) | ||
526 | for(substitution : l) | ||
527 | functionReference.parameterSubstitutions += substitution.toTerm | ||
528 | functionReference.checkFunctionCall(function) | ||
529 | return functionReference | ||
530 | } | ||
531 | def private checkFunctionCall(SymbolicValue value, Function referredFunction) { | ||
532 | if(value.parameterSubstitutions.size != referredFunction.parameters.size) | ||
533 | throw new LogicProblemBuilderException( | ||
534 | '''The function called has «referredFunction.parameters.size» parameters but it is called with «value.parameterSubstitutions.size»!''') | ||
535 | } | ||
536 | |||
537 | // Relation calls | ||
538 | def public call(Relation relation, TermDescription... substitution) { relation.call(substitution as Iterable<? extends TermDescription>)} | ||
539 | def public call(Relation relation, Iterable<? extends TermDescription> substitution) { | ||
540 | val relationReference = createSymbolicValue | ||
541 | relationReference.symbolicReference = relation | ||
542 | //println('''«relation.name»(«substitution.size»->«relation.parameters»)''') | ||
543 | for(value : substitution) | ||
544 | relationReference.parameterSubstitutions += value.toTerm | ||
545 | relationReference.checkRelationCall(relation) | ||
546 | return relationReference | ||
547 | } | ||
548 | def private checkRelationCall(SymbolicValue value, Relation referredRelation) { | ||
549 | if(value.parameterSubstitutions.size != referredRelation.parameters.size) { | ||
550 | throw new LogicProblemBuilderException( | ||
551 | '''The relation "«referredRelation.name»" called has «referredRelation.parameters.size» parameters but it is called with «value.parameterSubstitutions.size»!''') | ||
552 | } | ||
553 | } | ||
554 | |||
555 | // constant evaluation | ||
556 | def public call(Constant constant) { | ||
557 | val constantReference = createSymbolicValue | ||
558 | constantReference.symbolicReference = constant | ||
559 | return constantReference | ||
560 | } | ||
561 | |||
562 | |||
563 | } | ||