aboutsummaryrefslogtreecommitdiffstats
path: root/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend')
-rw-r--r--Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend357
1 files changed, 357 insertions, 0 deletions
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend
new file mode 100644
index 00000000..613cb3e4
--- /dev/null
+++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend
@@ -0,0 +1,357 @@
1package modes3.run
2
3import com.google.common.collect.ImmutableList
4import com.google.common.collect.ImmutableSet
5import hu.bme.mit.inf.dslreasoner.ecore2logic.EReferenceMapper_RelationsOverTypes_Trace
6import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic
7import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2LogicConfiguration
8import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace
9import hu.bme.mit.inf.dslreasoner.ecore2logic.EcoreMetamodelDescriptor
10import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsFactory
11import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsPackage
12import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel
13import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicProblemBuilder
14import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguagePackage
15import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition
16import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage
17import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult
18import hu.bme.mit.inf.dslreasoner.logic2ecore.Logic2Ecore
19import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic
20import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2LogicConfiguration
21import hu.bme.mit.inf.dslreasoner.viatra2logic.ViatraQuerySetDescriptor
22import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.Viatra2LogicAnnotationsPackage
23import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod
24import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints
25import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver
26import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy
27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.InstanceModel2Logic
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink
29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
30import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
31import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretation2Gml
32import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveConfiguration
33import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveElementConfiguration
34import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.StateCoderStrategy
35import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasoner
36import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
37import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation
38import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
39import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
40import hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz.GraphvizVisualiser
41import hu.bme.mit.inf.dslreasoner.workspace.FileSystemWorkspace
42import java.util.List
43import modes3.Modes3Factory
44import modes3.Modes3Package
45import modes3.queries.CloseTrains_step_2
46import modes3.queries.CloseTrains_step_3
47import modes3.queries.CloseTrains_step_4
48import modes3.queries.CloseTrains_step_5
49import modes3.queries.CloseTrains_step_6
50import modes3.queries.CloseTrains_step_7
51import modes3.queries.EndOfSiding_step_2
52import modes3.queries.EndOfSiding_step_3
53import modes3.queries.EndOfSiding_step_4
54import modes3.queries.EndOfSiding_step_5
55import modes3.queries.MisalignedTurnout_step_2
56import modes3.queries.MisalignedTurnout_step_3
57import modes3.queries.MisalignedTurnout_step_4
58import modes3.queries.MisalignedTurnout_step_5
59import modes3.queries.Modes3Queries
60import modes3.queries.TrainLocations_step_2
61import modes3.queries.TrainLocations_step_3
62import org.eclipse.emf.ecore.EClass
63import org.eclipse.emf.ecore.EObject
64import org.eclipse.emf.ecore.resource.Resource
65import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
66import org.eclipse.viatra.query.patternlanguage.emf.EMFPatternLanguageStandaloneSetup
67import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions
68import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchEMFBackendFactory
69import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory
70import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
71
72@FinalFieldsConstructor
73class Modes3ModelGenerator {
74 val MonitoringQuery monitoringQuery
75 val int modelSize
76
77 val ecore2Logic = new Ecore2Logic
78 val instanceModel2Logic = new InstanceModel2Logic
79 val viatra2Logic = new Viatra2Logic(ecore2Logic)
80 val solver = new ViatraReasoner
81 extension val LogicProblemBuilder = new LogicProblemBuilder
82
83 def generate() {
84 val metamodel = createMetamodelDescriptor()
85 val metamodelLogic = ecore2Logic.transformMetamodel(metamodel, new Ecore2LogicConfiguration)
86 val segment = ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.segment)
87 val connectedTo = ecore2Logic.relationOfReference(metamodelLogic.trace,
88 Modes3Package.eINSTANCE.segment_ConnectedTo)
89 val connectedToIndicator = (metamodelLogic.trace.
90 referenceMapperTrace as EReferenceMapper_RelationsOverTypes_Trace).indicators.get(
91 Modes3Package.eINSTANCE.segment_ConnectedTo)
92 val inverseAssertion = Assertion(
93 '''oppositeReference «connectedTo.name» «connectedTo.name»''',
94 Forall[
95 val src = addVar('''src''', segment)
96 val trg = addVar('''trg''', segment)
97 connectedToIndicator.call(src, trg) <=> connectedToIndicator.call(trg, src)
98 ]
99 )
100 metamodelLogic.output.assertions += inverseAssertion
101 val inverseAnnotation = Ecore2logicannotationsFactory.eINSTANCE.createInverseRelationAssertion => [
102 target = inverseAssertion
103 inverseA = connectedTo
104 inverseB = connectedTo
105 ]
106 metamodelLogic.output.annotations += inverseAnnotation
107 val initialModel = loadInitialModel()
108 val initialModelLogic = instanceModel2Logic.transform(metamodelLogic, initialModel)
109 val queries = loadQueries
110 val logic = viatra2Logic.transformQueries(queries, initialModelLogic, new Viatra2LogicConfiguration)
111 val config = new ViatraReasonerConfiguration => [
112 runtimeLimit = 3600
113 typeScopes => [
114 minNewElements = modelSize
115 maxNewElements = modelSize
116 minNewElementsByType => [
117// put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.train), modelSize / 5)
118// put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.turnout), modelSize / 5)
119// put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.simpleSegment), 3 * modelSize / 5)
120 ]
121 maxNewElementsByType => [
122 put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.train), modelSize / 5)
123 put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.turnout), modelSize / 5)
124 put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.simpleSegment), 3 * modelSize / 5)
125 ]
126 ]
127 solutionScope => [
128 numberOfRequiredSolutions = 1
129 ]
130 costObjectives += getObjective(ecore2Logic, metamodelLogic.trace)
131 scopeWeight = 6
132 nameNewElements = false
133 typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis
134 stateCoderStrategy = StateCoderStrategy.PairwiseNeighbourhood
135 scopePropagatorStrategy = new ScopePropagatorStrategy.Polyhedral(
136 PolyhedralScopePropagatorConstraints.Relational, PolyhedralScopePropagatorSolver.Clp)
137 hints += new Modes3TypeScopeHint(ecore2Logic, metamodelLogic.trace)
138 unitPropagationPatternGenerators += new Modes3UnitPropagationGenerator(ecore2Logic, metamodelLogic.trace)
139 debugConfiguration => [
140 partialInterpretatioVisualiser = new GraphvizVisualiser
141// partalInterpretationVisualisationFrequency = 50
142 ]
143 documentationLevel = DocumentationLevel.NORMAL
144 ]
145 val workspace = new FileSystemWorkspace("output/", "")
146 workspace.writeModel(logic.output, "problem.logicproblem")
147 val solution = solver.solve(logic.output, config, workspace)
148 if (solution instanceof ModelResult) {
149 println("Saving generated solutions")
150 val logic2Ecore = new Logic2Ecore(ecore2Logic)
151 val interpretations = solver.getInterpretations(solution)
152 for (representationIndex : 0 ..< interpretations.size) {
153 val interpretation = interpretations.get(representationIndex)
154 val representationNumber = representationIndex + 1
155 if (interpretation instanceof PartialModelAsLogicInterpretation) {
156 val representation = interpretation.partialInterpretation
157 workspace.writeModel(representation, '''solution«representationNumber».partialinterpretation''')
158 val partialInterpretation2GML = new PartialInterpretation2Gml
159 val gml = partialInterpretation2GML.transform(representation)
160 workspace.writeText('''solution«representationNumber».gml''', gml)
161 val model = logic2Ecore.transformInterpretation(interpretation, metamodelLogic.trace)
162 val iterator = model.eAllContents
163 var int id = 0
164 while (iterator.hasNext) {
165 val obj = iterator.next
166 val idFeature = obj.eClass.EAllAttributes.findFirst[name == 'id']
167 if (idFeature !== null) {
168 obj.eSet(idFeature, id)
169 id++
170 }
171 }
172 workspace.writeModel(model, '''solution«representationNumber».modes3''')
173 if (representation.newElements.size < 160) {
174 val rootType = (representation.problem.types.findFirst [
175 name == "Modes3ModelRoot class DefinedPart"
176 ] as TypeDefinition)
177 val rootIntepretation = representation.partialtypeinterpratation.filter(
178 PartialComplexTypeInterpretation).findFirst [
179 interpretationOf.name == "Modes3ModelRoot class"
180 ]
181 rootIntepretation.elements.removeAll(rootType.elements)
182 representation.problem.elements.removeAll(rootType.elements)
183 for (relationInterpretation : representation.partialrelationinterpretation) {
184 relationInterpretation.relationlinks.removeIf [ link |
185 if (link instanceof BinaryElementRelationLink) {
186 rootType.elements.contains(link.param1) ||
187 rootType.elements.contains(link.param2)
188 } else {
189 false
190 }
191 ]
192 }
193 rootType.elements.clear
194 val visualiser = new GraphvizVisualiser
195 val visualisation = visualiser.visualiseConcretization(representation)
196 visualisation.writeToFile(workspace, '''solution«representationNumber».png''')
197 }
198 } else {
199 workspace.writeText('''solution«representationNumber».txt''', interpretation.toString)
200 }
201 }
202 } else {
203 println("Failed to solve problem")
204 val partial = logic.output
205 workspace.writeModel(partial, "solution.partialinterpretation")
206 }
207 }
208
209 static def createMetamodelDescriptor() {
210 val eClasses = ImmutableList.copyOf(Modes3Package.eINSTANCE.EClassifiers.filter(EClass))
211 new EcoreMetamodelDescriptor(
212 eClasses,
213 emptySet,
214 false,
215 emptyList,
216 emptyList,
217 ImmutableList.copyOf(eClasses.flatMap[EReferences]),
218 emptyList
219 )
220 }
221
222 static def List<EObject> loadInitialModel() {
223 #[Modes3Factory.eINSTANCE.createModes3ModelRoot]
224 }
225
226 def loadQueries() {
227 val patternsBuilder = ImmutableList.builder
228 patternsBuilder.addAll(Modes3Queries.instance.specifications)
229 val patterns = patternsBuilder.build
230 val validationPatterns = ImmutableSet.copyOf(patterns.filter [ pattern |
231 pattern.allAnnotations.exists[name == "Constraint"]
232 ])
233 new ViatraQuerySetDescriptor(
234 patterns,
235 validationPatterns,
236 emptyMap
237 )
238 }
239
240 def getObjective(Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) {
241 new CostObjectiveConfiguration => [
242 switch (monitoringQuery) {
243 case closeTrains: {
244 elements += new CostObjectiveElementConfiguration => [
245 patternQualifiedName = CloseTrains_step_2.instance.fullyQualifiedName
246 weight = 14 + 53 + 11
247 ]
248 elements += new CostObjectiveElementConfiguration => [
249 patternQualifiedName = CloseTrains_step_3.instance.fullyQualifiedName
250 weight = 21 + 14
251 ]
252 elements += new CostObjectiveElementConfiguration => [
253 patternQualifiedName = CloseTrains_step_4.instance.fullyQualifiedName
254 weight = 14 + 44 + 14 + 9
255 ]
256 elements += new CostObjectiveElementConfiguration => [
257 patternQualifiedName = CloseTrains_step_5.instance.fullyQualifiedName
258 weight = 14 + 41 + 11
259 ]
260 elements += new CostObjectiveElementConfiguration => [
261 patternQualifiedName = CloseTrains_step_6.instance.fullyQualifiedName
262 weight = 27
263 ]
264 elements += new CostObjectiveElementConfiguration => [
265 patternQualifiedName = CloseTrains_step_7.instance.fullyQualifiedName
266 weight = 48
267 ]
268 hint = new CloseTrainsObjectiveHint(ecore2Logic, ecore2LogicTrace)
269 }
270 case trainLocations: {
271 elements += new CostObjectiveElementConfiguration => [
272 patternQualifiedName = TrainLocations_step_2.instance.fullyQualifiedName
273 weight = 14 + 53 + 11
274 ]
275 elements += new CostObjectiveElementConfiguration => [
276 patternQualifiedName = TrainLocations_step_3.instance.fullyQualifiedName
277 weight = 48
278 ]
279 hint = new TrainLocationsObjectiveHint(ecore2Logic, ecore2LogicTrace)
280 }
281 case misalignedTurnout: {
282 elements += new CostObjectiveElementConfiguration => [
283 patternQualifiedName = MisalignedTurnout_step_2.instance.fullyQualifiedName
284 weight = 14 + 53 + 11
285 ]
286 elements += new CostObjectiveElementConfiguration => [
287 patternQualifiedName = MisalignedTurnout_step_3.instance.fullyQualifiedName
288 weight = 108
289 ]
290 elements += new CostObjectiveElementConfiguration => [
291 patternQualifiedName = MisalignedTurnout_step_4.instance.fullyQualifiedName
292 weight = 27
293 ]
294 elements += new CostObjectiveElementConfiguration => [
295 patternQualifiedName = MisalignedTurnout_step_5.instance.fullyQualifiedName
296 weight = 48
297 ]
298 hint = new MisalignedTurnoutObjectiveHint(ecore2Logic, ecore2LogicTrace)
299 }
300 case endOfSiding: {
301 elements += new CostObjectiveElementConfiguration => [
302 patternQualifiedName = EndOfSiding_step_2.instance.fullyQualifiedName
303 weight = 14 + 53 + 11
304 ]
305 elements += new CostObjectiveElementConfiguration => [
306 patternQualifiedName = EndOfSiding_step_3.instance.fullyQualifiedName
307 weight = 21 + 14
308 ]
309 elements += new CostObjectiveElementConfiguration => [
310 patternQualifiedName = EndOfSiding_step_4.instance.fullyQualifiedName
311 weight = 14 + 35 + 21 + 15 + 14 + 21 + 15 + 11
312 ]
313 elements += new CostObjectiveElementConfiguration => [
314 patternQualifiedName = EndOfSiding_step_5.instance.fullyQualifiedName
315 weight = 48
316 ]
317 hint = new EndOfSidingObjectiveHint(ecore2Logic, ecore2LogicTrace)
318 }
319 default:
320 throw new IllegalArgumentException("Unknown monitoring query: " + monitoringQuery)
321 }
322 kind = ObjectiveKind.HIGHER_IS_BETTER
323 threshold = ObjectiveThreshold.NO_THRESHOLD
324 findExtremum = true
325 ]
326 }
327
328 def static init() {
329 EMFPatternLanguageStandaloneSetup.doSetup
330 ViatraQueryEngineOptions.setSystemDefaultBackends(ReteBackendFactory.INSTANCE, ReteBackendFactory.INSTANCE,
331 LocalSearchEMFBackendFactory.INSTANCE)
332 LogiclanguagePackage.eINSTANCE.class
333 LogicproblemPackage.eINSTANCE.class
334 PartialinterpretationPackage.eINSTANCE.class
335 Ecore2logicannotationsPackage.eINSTANCE.class
336 Viatra2LogicAnnotationsPackage.eINSTANCE.class
337 Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*", new XMIResourceFactoryImpl)
338 }
339
340 def static void main(String[] args) {
341 if (args.length != 2) {
342 System.err.println("Usage: <query> <model size>")
343 }
344 val monitoringQuery = MonitoringQuery.valueOf(args.get(0))
345 val modelSize = Integer.parseInt(args.get(1))
346 init()
347 val generator = new Modes3ModelGenerator(monitoringQuery, modelSize)
348 generator.generate()
349 }
350
351 private static enum MonitoringQuery {
352 closeTrains,
353 trainLocations,
354 endOfSiding,
355 misalignedTurnout
356 }
357}