diff options
Diffstat (limited to 'Domains/ca.mcgill.rtgmrt.example.modes3/src')
8 files changed, 1713 insertions, 0 deletions
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql new file mode 100644 index 00000000..d22bdd8b --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql | |||
@@ -0,0 +1,295 @@ | |||
1 | package modes3.queries | ||
2 | |||
3 | import "http://www.ece.mcgill.ca/wcet/modes3" | ||
4 | |||
5 | pattern connectedTo(S1 : Segment, S2 : Segment) { | ||
6 | Segment.connectedTo(S1, S2); | ||
7 | } | ||
8 | |||
9 | @Constraint(message = "connectedToNotSymmetric", severity = "error", key = { S1, S2 }) | ||
10 | pattern connectedToNotSymmetric(S1 : Segment, S2 : Segment) { | ||
11 | Segment.connectedTo(S1, S2); | ||
12 | neg find connectedTo(S2, S1); | ||
13 | } | ||
14 | |||
15 | @Constraint(message = "connectedToReflexive", severity = "error", key = { S }) | ||
16 | pattern connectedToReflexive(S : Segment) { | ||
17 | Segment.connectedTo(S, S); | ||
18 | } | ||
19 | |||
20 | pattern turnoutOutput(T : Turnout, S : Segment) { | ||
21 | Turnout.straight(T, S); | ||
22 | } or { | ||
23 | Turnout.divergent(T, S); | ||
24 | } | ||
25 | |||
26 | @Constraint(message = "outputReflexive", severity = "error", key = { T }) | ||
27 | pattern outputReflexive(T : Turnout) { | ||
28 | find turnoutOutput(T, T); | ||
29 | } | ||
30 | |||
31 | @Constraint(message = "turnoutOutputsAreSame", severity = "error", key = { T }) | ||
32 | pattern turnoutOutputsAreSame(T : Turnout) { | ||
33 | Turnout.straight(T, S); | ||
34 | Turnout.divergent(T, S); | ||
35 | } | ||
36 | |||
37 | pattern output(S1 : Segment, S2 : Segment) { | ||
38 | Segment.connectedTo(S1, S2); | ||
39 | } or { | ||
40 | find turnoutOutput(S1, S2); | ||
41 | } | ||
42 | |||
43 | @Constraint(message = "tooManyInputsOfSegment", severity = "error", key = { S }) | ||
44 | pattern tooManyInputsOfSegment(S : SimpleSegment) { | ||
45 | find output(I1, S); | ||
46 | find output(I2, S); | ||
47 | find output(I3, S); | ||
48 | I1 != I2; | ||
49 | I1 != I3; | ||
50 | I2 != I3; | ||
51 | } | ||
52 | |||
53 | @Constraint(message = "turnoutConnectedToBothOutputs", severity = "error", key = { T }) | ||
54 | pattern turnoutConnectedToBothOutputs(T : Turnout) { | ||
55 | Turnout.straight(T, Straight); | ||
56 | Turnout.divergent(T, Divergent); | ||
57 | Segment.connectedTo(T, Straight); | ||
58 | Segment.connectedTo(T, Divergent); | ||
59 | } | ||
60 | |||
61 | pattern adjacent(S1 : Segment, S2 : Segment) { | ||
62 | find output(S1, S2); | ||
63 | } or { | ||
64 | find turnoutOutput(S2, S1); | ||
65 | } | ||
66 | |||
67 | @Constraint(message = "turnoutConnectedToBothOutputs", severity = "error", key = { T }) | ||
68 | pattern tooManyInputsOfTurnout(T : Turnout) { | ||
69 | find adjacent(I1, T); | ||
70 | find adjacent(I2, T); | ||
71 | find adjacent(I3, T); | ||
72 | find adjacent(I4, T); | ||
73 | I1 != I2; | ||
74 | I1 != I3; | ||
75 | I1 != I4; | ||
76 | I2 != I3; | ||
77 | I2 != I4; | ||
78 | I3 != I4; | ||
79 | } | ||
80 | |||
81 | pattern inputsOfTurnout(T : Turnout) { | ||
82 | find adjacent(I1, T); | ||
83 | find adjacent(I2, T); | ||
84 | find adjacent(I3, T); | ||
85 | I1 != I2; | ||
86 | I1 != I3; | ||
87 | I2 != I3; | ||
88 | } | ||
89 | |||
90 | @Constraint(message = "tooFewInputsOfTurnout", severity = "error", key = { T }) | ||
91 | pattern tooFewInputsOfTurnout(T : Turnout) { | ||
92 | neg find inputsOfTurnout(T); | ||
93 | } | ||
94 | |||
95 | pattern reachable(S1 : Segment, S2 : Segment) { | ||
96 | S1 == S2; | ||
97 | } or { | ||
98 | find adjacent+(S1, S2); | ||
99 | } | ||
100 | |||
101 | @Constraint(message = "unreachable", severity = "error", key = { S1, S2 }) | ||
102 | pattern unreachable(S1 : Segment, S2 : Segment) { | ||
103 | neg find reachable(S1, S2); | ||
104 | } | ||
105 | |||
106 | // | ||
107 | // closeTrains | ||
108 | // | ||
109 | |||
110 | pattern closeTrains_step_2(in train : Train) { | ||
111 | // frame->t1 = model->trains[i0]; | ||
112 | // frame->start = frame->t1->location; | ||
113 | // if(frame->start != 0){ | ||
114 | // ... | ||
115 | // } | ||
116 | // + OUTER FOR LOOP COUNTER INCREMENT | ||
117 | Train(train); | ||
118 | } | ||
119 | |||
120 | pattern closeTrains_step_3(in train : Train, in start : Segment) { | ||
121 | // int loop_bound1 = frame->start->connected_to_count; | ||
122 | // for (int i1 = 0; i1 < loop_bound1; i1++) { LOOP COUNTER INCREMENT IS NOT INCLUDED HERE | ||
123 | // ... | ||
124 | // } | ||
125 | Train.location(train, start); | ||
126 | } | ||
127 | |||
128 | pattern closeTrains_step_4(in train : Train, in start : Segment, in middle : Segment) { | ||
129 | // frame->middle = frame->start->connected_to[i1]; | ||
130 | // int loop_bound2 = frame->middle->connected_to_count; | ||
131 | |||
132 | // for (int i2 = 0; i2 < loop_bound2; i2++) { LOOP COUNTER INCREMENT IS NOT INCLUDED HERE | ||
133 | // ... | ||
134 | // } | ||
135 | // + OUTER FOR LOOP COUNTER INCREMENT | ||
136 | Train.location(train, start); | ||
137 | Segment.connectedTo(start, middle); | ||
138 | } | ||
139 | |||
140 | pattern closeTrains_step_5(in train : Train, in start : Segment, in middle : Segment, in end : Segment) { | ||
141 | // frame->end = frame->middle->connected_to[i2]; | ||
142 | // if (frame->start != frame->end) { | ||
143 | // ... | ||
144 | // } | ||
145 | // + OUTER FOR LOOP COUNTER INCREMENT | ||
146 | Train.location(train, start); | ||
147 | Segment.connectedTo(start, middle); | ||
148 | Segment.connectedTo(middle, end); | ||
149 | } | ||
150 | |||
151 | pattern closeTrains_step_6(in train : Train, in start : Segment, in middle : Segment, in end : Segment) { | ||
152 | // frame->t2 = frame->end->train; | ||
153 | // if (frame->t2 != 0) { | ||
154 | // ... | ||
155 | // } | ||
156 | Train.location(train, start); | ||
157 | Segment.connectedTo(start, middle); | ||
158 | Segment.connectedTo(middle, end); | ||
159 | start != end; | ||
160 | } | ||
161 | |||
162 | pattern closeTrains_step_7(in train : Train, in start : Segment, in middle : Segment, in end : Segment, in otherTrain : Train) { | ||
163 | // results->matches[match_cntr].start = frame->start; | ||
164 | // results->matches[match_cntr++].end = frame->end; | ||
165 | Train.location(train, start); | ||
166 | Segment.connectedTo(start, middle); | ||
167 | Segment.connectedTo(middle, end); | ||
168 | start != end; | ||
169 | Segment.occupiedBy(end, otherTrain); | ||
170 | } | ||
171 | |||
172 | // | ||
173 | // trainLocations | ||
174 | // | ||
175 | |||
176 | pattern trainLocations_step_2(in train : Train) { | ||
177 | // frame->train = model->trains[i0]; | ||
178 | // frame->location = frame->train->location; | ||
179 | // if (frame->location != NULL) { | ||
180 | // ... | ||
181 | // } | ||
182 | |||
183 | Train(train); | ||
184 | } | ||
185 | |||
186 | pattern trainLocations_step_3(in train : Train, in location : Segment) { | ||
187 | // results->matches[match_cntr].location = frame->location; | ||
188 | // results->matches[match_cntr++].train = frame->train; | ||
189 | Train(train); | ||
190 | Train.location(train, location); | ||
191 | } | ||
192 | |||
193 | // | ||
194 | // misalignedTurnout | ||
195 | // | ||
196 | |||
197 | pattern misalignedTurnout_step_2(in turnout : Turnout) { | ||
198 | // frame->turnout = model->turnouts[i0]; | ||
199 | // frame->location = frame->turnout->straight; | ||
200 | // if (frame->location != NULL) { | ||
201 | // ... | ||
202 | // } | ||
203 | Turnout(turnout); | ||
204 | } | ||
205 | |||
206 | pattern misalignedTurnout_step_3(in turnout : Turnout, in location : Segment) { | ||
207 | // Segment *disconnected = ((Segment *)frame->turnout); | ||
208 | // if (disconnected->connected_to[0] != frame->location && | ||
209 | // disconnected->connected_to[1] != frame->location) { | ||
210 | // ... | ||
211 | // } | ||
212 | Turnout(turnout); | ||
213 | Turnout.straight(turnout, location); | ||
214 | } | ||
215 | |||
216 | pattern misalignedTurnout_step_4(in turnout : Turnout, in location : Segment) { | ||
217 | // frame->train = frame->location->train; | ||
218 | // if (frame->train != NULL) { | ||
219 | // ... | ||
220 | // } | ||
221 | Turnout(turnout); | ||
222 | Turnout.straight(turnout, location); | ||
223 | neg find connectedSegmentsDirected(turnout, location); | ||
224 | } | ||
225 | |||
226 | pattern misalignedTurnout_step_5(in turnout : Turnout, in location : Segment, in train : Train) { | ||
227 | // results->matches[match_cntr].start = frame->start; | ||
228 | // results->matches[match_cntr++].end = frame->end; | ||
229 | Turnout(turnout); | ||
230 | Turnout.straight(turnout, location); | ||
231 | neg find connectedSegmentsDirected(turnout, location); | ||
232 | Segment.occupiedBy(location, train); | ||
233 | } | ||
234 | |||
235 | pattern connectedSegmentsDirected(s1 : Segment, s2 : Segment) { | ||
236 | Segment.connectedTo(s1, s2); | ||
237 | } | ||
238 | |||
239 | // | ||
240 | // endOfSiding | ||
241 | // | ||
242 | |||
243 | pattern endOfSiding_step_2(in train : Train) { | ||
244 | // frame->train = model->trains[i0]; | ||
245 | // frame->location = frame->train->location; | ||
246 | // if (frame->location != NULL) { | ||
247 | // ... | ||
248 | // } | ||
249 | |||
250 | Train(train); | ||
251 | } | ||
252 | |||
253 | pattern endOfSiding_step_3(in train : Train, in location : Segment) { | ||
254 | // int loop_bound1 = frame->location->connected_to_count; | ||
255 | // for (int i1 = 0; i1 < loop_bound1; i1++) { | ||
256 | // ... | ||
257 | // } | ||
258 | Train(train); | ||
259 | Train.location(train, location); | ||
260 | } | ||
261 | |||
262 | pattern endOfSiding_step_4(in train : Train, in location : Segment, in end : Segment) { | ||
263 | // frame->end = frame->location->connected_to[i1]; | ||
264 | // if (frame->end != NULL && | ||
265 | // frame->end->connected_to[1] == frame->location && | ||
266 | // frame->end->connected_to[0] == NULL) { | ||
267 | // ... | ||
268 | // } | ||
269 | // if (frame->end != NULL && | ||
270 | // frame->end->connected_to[0] == frame->location && | ||
271 | // frame->end->connected_to[1] == NULL) { | ||
272 | // ... | ||
273 | // } | ||
274 | Train(train); | ||
275 | Train.location(train, location); | ||
276 | Segment.connectedTo(location, end); | ||
277 | } | ||
278 | |||
279 | pattern endOfSiding_step_5(in train : Train, in location : Segment, in end : Segment) { | ||
280 | // results->matches[match_cntr].location = frame->location; | ||
281 | // results->matches[match_cntr++].train = frame->train; | ||
282 | // ...OR... | ||
283 | // results->matches[match_cntr].location = frame->location; | ||
284 | // results->matches[match_cntr++].train = frame->train; | ||
285 | Train(train); | ||
286 | Train.location(train, location); | ||
287 | Segment.connectedTo(location, end); | ||
288 | neg find multipleConnectedTo(end); | ||
289 | } | ||
290 | |||
291 | pattern multipleConnectedTo(s : Segment) { | ||
292 | Segment.connectedTo(s, n1); | ||
293 | Segment.connectedTo(s, n2); | ||
294 | n1 != n2; | ||
295 | } | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/CloseTrainsObjectiveHint.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/CloseTrainsObjectiveHint.xtend new file mode 100644 index 00000000..519a228a --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/CloseTrainsObjectiveHint.xtend | |||
@@ -0,0 +1,201 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilderFactory | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatch | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatchers | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint | ||
10 | import java.util.Collection | ||
11 | import java.util.Map | ||
12 | import modes3.Modes3Package | ||
13 | import modes3.queries.CloseTrains_step_2 | ||
14 | import modes3.queries.CloseTrains_step_3 | ||
15 | import modes3.queries.CloseTrains_step_4 | ||
16 | import modes3.queries.CloseTrains_step_5 | ||
17 | import modes3.queries.CloseTrains_step_6 | ||
18 | import modes3.queries.CloseTrains_step_7 | ||
19 | |||
20 | class CloseTrainsObjectiveHint extends CostObjectiveHint { | ||
21 | val Type segmentType | ||
22 | val Type trainType | ||
23 | |||
24 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
25 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
26 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
27 | trainType = ecore2LogicTrace.TypeofEClass(train) | ||
28 | } | ||
29 | |||
30 | override isExact() { | ||
31 | true | ||
32 | } | ||
33 | |||
34 | override createPolyhedronExtensionOperator(Map<String, CostElementMatchers> costElementMatchers) { | ||
35 | val step2 = costElementMatchers.get(CloseTrains_step_2.instance.fullyQualifiedName) | ||
36 | val step3 = costElementMatchers.get(CloseTrains_step_3.instance.fullyQualifiedName) | ||
37 | val step4 = costElementMatchers.get(CloseTrains_step_4.instance.fullyQualifiedName) | ||
38 | val step5 = costElementMatchers.get(CloseTrains_step_5.instance.fullyQualifiedName) | ||
39 | val step6 = costElementMatchers.get(CloseTrains_step_6.instance.fullyQualifiedName) | ||
40 | val step7 = costElementMatchers.get(CloseTrains_step_7.instance.fullyQualifiedName); | ||
41 | |||
42 | [ | ||
43 | val objectiveBuilder = createBuilder | ||
44 | |||
45 | for (m : step2.matches) { | ||
46 | val dimension = getDimension(m.match) | ||
47 | objectiveBuilder.add(step2.weight, dimension) | ||
48 | dimension.tightenLowerBound(0) | ||
49 | if (m.multi) { | ||
50 | createBuilder.add(1, dimension).add(-1, trainType).build.assertEqualsTo(0) | ||
51 | } else { | ||
52 | dimension.tightenUpperBound(1) | ||
53 | if (m.must) { | ||
54 | dimension.tightenLowerBound(1) | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | val step3Matches = step3.matches | ||
60 | for (m : step3Matches) { | ||
61 | val dimension = getDimension(m.match) | ||
62 | objectiveBuilder.add(step3.weight, dimension) | ||
63 | dimension.tightenLowerBound(0) | ||
64 | if (!m.multi) { | ||
65 | dimension.tightenUpperBound(1) | ||
66 | if (m.must) { | ||
67 | dimension.tightenLowerBound(1) | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | for (pair : step3Matches.groupBy[step2.projectMayMatch(match, 2)].entrySet) { | ||
72 | val multiplicityBuilder = createBuilder | ||
73 | for (m : pair.value) { | ||
74 | multiplicityBuilder.add(1, m.match) | ||
75 | } | ||
76 | multiplicityBuilder.add(-1, pair.key) | ||
77 | multiplicityBuilder.build.assertEqualsTo(0) | ||
78 | } | ||
79 | boundLimit(step3Matches, 2, trainType, 1) | ||
80 | boundLimit(step3Matches, 3, segmentType, 1) | ||
81 | |||
82 | val step4Matches = step4.matches | ||
83 | for (m : step4Matches) { | ||
84 | val dimension = getDimension(m.match) | ||
85 | objectiveBuilder.add(step4.weight, dimension) | ||
86 | dimension.tightenLowerBound(0) | ||
87 | if (!m.multi) { | ||
88 | dimension.tightenUpperBound(1) | ||
89 | if (m.must) { | ||
90 | dimension.tightenLowerBound(1) | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | for (pair : step4Matches.groupBy[step3.projectMayMatch(match, 2, 3)].entrySet) { | ||
95 | val multiplicityBuilder = createBuilder | ||
96 | for (m : pair.value) { | ||
97 | multiplicityBuilder.add(1, m.match) | ||
98 | } | ||
99 | multiplicityBuilder.add(-2, pair.key) | ||
100 | multiplicityBuilder.build.tightenUpperBound(0) | ||
101 | } | ||
102 | boundLimit(step4Matches, 2, trainType, 2) | ||
103 | boundLimit(step4Matches, 3, segmentType, 2) | ||
104 | boundLimit(step4Matches, 4, segmentType, 2) | ||
105 | |||
106 | val step5Matches = step5.matches | ||
107 | for (m : step5Matches) { | ||
108 | val dimension = getDimension(m.match) | ||
109 | objectiveBuilder.add(step5.weight, dimension) | ||
110 | dimension.tightenLowerBound(0) | ||
111 | if (!m.multi) { | ||
112 | dimension.tightenUpperBound(1) | ||
113 | if (m.must) { | ||
114 | dimension.tightenLowerBound(1) | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | for (pair : step5Matches.groupBy[step4.projectMayMatch(match, 2, 3, 4)].entrySet) { | ||
119 | val multiplicityBuilder = createBuilder | ||
120 | for (m : pair.value) { | ||
121 | multiplicityBuilder.add(1, m.match) | ||
122 | } | ||
123 | multiplicityBuilder.add(-2, pair.key) | ||
124 | multiplicityBuilder.build.tightenUpperBound(0) | ||
125 | } | ||
126 | boundLimit(step5Matches, 2, trainType, 4) | ||
127 | boundLimit(step5Matches, 3, segmentType, 4) | ||
128 | boundLimit(step5Matches, 4, segmentType, 4) | ||
129 | boundLimit(step5Matches, 5, segmentType, 4) | ||
130 | |||
131 | val step6Matches = step6.matches | ||
132 | for (m : step6Matches) { | ||
133 | val dimension = getDimension(m.match) | ||
134 | objectiveBuilder.add(step6.weight, dimension) | ||
135 | dimension.tightenLowerBound(0) | ||
136 | if (m.multi) { | ||
137 | if (m.match.get(3) == m.match.get(5)) { | ||
138 | createBuilder.add(2, m.match).add(-1, step5.projectMayMatch(m.match, 2, 3, 4, 5)).build. | ||
139 | assertEqualsTo(0) | ||
140 | } else { | ||
141 | createBuilder.add(1, m.match).add(-1, step5.projectMayMatch(m.match, 2, 3, 4, 5)).build. | ||
142 | assertEqualsTo(0) | ||
143 | } | ||
144 | } else { | ||
145 | dimension.tightenUpperBound(1) | ||
146 | if (m.must) { | ||
147 | dimension.tightenLowerBound(1) | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | boundLimit(step6Matches, 2, trainType, 2) | ||
152 | boundLimit(step6Matches, 3, segmentType, 2) | ||
153 | boundLimit(step6Matches, 4, segmentType, 2) | ||
154 | boundLimit(step6Matches, 5, segmentType, 2) | ||
155 | |||
156 | val step7Matches = step7.matches | ||
157 | for (m : step7Matches) { | ||
158 | val dimension = getDimension(m.match) | ||
159 | objectiveBuilder.add(step7.weight, dimension) | ||
160 | dimension.tightenLowerBound(0) | ||
161 | if (!m.multi) { | ||
162 | dimension.tightenUpperBound(1) | ||
163 | if (m.must) { | ||
164 | dimension.tightenLowerBound(1) | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | for (pair : step7Matches.groupBy[step6.projectMayMatch(match, 2, 3, 4, 5)].entrySet) { | ||
169 | val multiplicityBuilder = createBuilder | ||
170 | for (m : pair.value) { | ||
171 | multiplicityBuilder.add(1, m.match) | ||
172 | } | ||
173 | multiplicityBuilder.add(-1, pair.key) | ||
174 | multiplicityBuilder.build.tightenUpperBound(0) | ||
175 | } | ||
176 | boundLimit(step7Matches, 2, trainType, 2) | ||
177 | boundLimit(step7Matches, 3, segmentType, 2) | ||
178 | boundLimit(step7Matches, 4, segmentType, 2) | ||
179 | boundLimit(step7Matches, 5, segmentType, 2) | ||
180 | boundLimit(step7Matches, 6, trainType, 2) | ||
181 | |||
182 | objectiveBuilder.buildWithBounds | ||
183 | ] | ||
184 | } | ||
185 | |||
186 | private static def boundLimit(extension ExtendedLinearExpressionBuilderFactory factory, | ||
187 | Collection<CostElementMatch> matches, int index, Type type, int count) { | ||
188 | for (pair : matches.groupBy[match.get(index)].entrySet) { | ||
189 | val multiplicityBuilder = createBuilder | ||
190 | for (m : pair.value) { | ||
191 | multiplicityBuilder.add(1, m.match) | ||
192 | } | ||
193 | if (CostElementMatchers.isMulti(pair.key)) { | ||
194 | multiplicityBuilder.add(-count, type) | ||
195 | multiplicityBuilder.build.tightenUpperBound(0) | ||
196 | } else { | ||
197 | multiplicityBuilder.build.tightenUpperBound(count) | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | } | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/EndOfSidingObjectiveHint.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/EndOfSidingObjectiveHint.xtend new file mode 100644 index 00000000..f7e23a57 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/EndOfSidingObjectiveHint.xtend | |||
@@ -0,0 +1,139 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilderFactory | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatch | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatchers | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint | ||
10 | import java.util.Collection | ||
11 | import java.util.Map | ||
12 | import modes3.Modes3Package | ||
13 | import modes3.queries.EndOfSiding_step_2 | ||
14 | import modes3.queries.EndOfSiding_step_3 | ||
15 | import modes3.queries.EndOfSiding_step_4 | ||
16 | import modes3.queries.EndOfSiding_step_5 | ||
17 | |||
18 | class EndOfSidingObjectiveHint extends CostObjectiveHint { | ||
19 | val Type segmentType | ||
20 | val Type trainType | ||
21 | |||
22 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
23 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
24 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
25 | trainType = ecore2LogicTrace.TypeofEClass(train) | ||
26 | } | ||
27 | |||
28 | override isExact() { | ||
29 | true | ||
30 | // false | ||
31 | } | ||
32 | |||
33 | override createPolyhedronExtensionOperator(Map<String, CostElementMatchers> costElementMatchers) { | ||
34 | val step2 = costElementMatchers.get(EndOfSiding_step_2.instance.fullyQualifiedName) | ||
35 | val step3 = costElementMatchers.get(EndOfSiding_step_3.instance.fullyQualifiedName) | ||
36 | val step4 = costElementMatchers.get(EndOfSiding_step_4.instance.fullyQualifiedName) | ||
37 | val step5 = costElementMatchers.get(EndOfSiding_step_5.instance.fullyQualifiedName); | ||
38 | |||
39 | [ | ||
40 | val objectiveBuilder = createBuilder | ||
41 | |||
42 | for (m : step2.matches) { | ||
43 | val dimension = getDimension(m.match) | ||
44 | objectiveBuilder.add(step2.weight, dimension) | ||
45 | dimension.tightenLowerBound(0) | ||
46 | if (m.multi) { | ||
47 | createBuilder.add(1, dimension).add(-1, trainType).build.assertEqualsTo(0) | ||
48 | } else { | ||
49 | dimension.tightenUpperBound(1) | ||
50 | if (m.must) { | ||
51 | dimension.tightenLowerBound(1) | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | val step3Matches = step3.matches | ||
57 | for (m : step3Matches) { | ||
58 | val dimension = getDimension(m.match) | ||
59 | objectiveBuilder.add(step3.weight, dimension) | ||
60 | dimension.tightenLowerBound(0) | ||
61 | if (!m.multi) { | ||
62 | dimension.tightenUpperBound(1) | ||
63 | if (m.must) { | ||
64 | dimension.tightenLowerBound(1) | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | for (pair : step3Matches.groupBy[step2.projectMayMatch(match, 2)].entrySet) { | ||
69 | val multiplicityBuilder = createBuilder | ||
70 | for (m : pair.value) { | ||
71 | multiplicityBuilder.add(1, m.match) | ||
72 | } | ||
73 | multiplicityBuilder.add(-1, pair.key) | ||
74 | multiplicityBuilder.build.assertEqualsTo(0) | ||
75 | } | ||
76 | boundLimit(step3Matches, 2, trainType, 1) | ||
77 | boundLimit(step3Matches, 3, segmentType, 1) | ||
78 | |||
79 | val step4Matches = step4.matches | ||
80 | for (m : step4Matches) { | ||
81 | val dimension = getDimension(m.match) | ||
82 | objectiveBuilder.add(step4.weight, dimension) | ||
83 | dimension.tightenLowerBound(0) | ||
84 | if (!m.multi) { | ||
85 | dimension.tightenUpperBound(1) | ||
86 | if (m.must) { | ||
87 | dimension.tightenLowerBound(1) | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | for (pair : step4Matches.groupBy[step3.projectMayMatch(match, 2, 3)].entrySet) { | ||
92 | val multiplicityBuilder = createBuilder | ||
93 | for (m : pair.value) { | ||
94 | multiplicityBuilder.add(1, m.match) | ||
95 | } | ||
96 | multiplicityBuilder.add(-2, pair.key) | ||
97 | multiplicityBuilder.build.tightenUpperBound(0) | ||
98 | } | ||
99 | boundLimit(step4Matches, 2, trainType, 2) | ||
100 | boundLimit(step4Matches, 3, segmentType, 2) | ||
101 | boundLimit(step4Matches, 4, segmentType, 2) | ||
102 | |||
103 | val step5Matches = step5.matches | ||
104 | for (m : step5Matches) { | ||
105 | val dimension = getDimension(m.match) | ||
106 | objectiveBuilder.add(step5.weight, dimension) | ||
107 | dimension.tightenLowerBound(0) | ||
108 | if (!m.multi) { | ||
109 | dimension.tightenUpperBound(1) | ||
110 | if (m.must) { | ||
111 | dimension.tightenLowerBound(1) | ||
112 | } | ||
113 | } | ||
114 | createBuilder.add(1, m.match).add(-1, step4.projectMayMatch(m.match, 2, 3, 4)).build.tightenUpperBound(0) | ||
115 | } | ||
116 | boundLimit(step5Matches, 2, trainType, 1) | ||
117 | boundLimit(step5Matches, 3, segmentType, 2) | ||
118 | boundLimit(step5Matches, 4, segmentType, 1) | ||
119 | |||
120 | objectiveBuilder.buildWithBounds | ||
121 | ] | ||
122 | } | ||
123 | |||
124 | private static def boundLimit(extension ExtendedLinearExpressionBuilderFactory factory, | ||
125 | Collection<CostElementMatch> matches, int index, Type type, int count) { | ||
126 | for (pair : matches.groupBy[match.get(index)].entrySet) { | ||
127 | val multiplicityBuilder = createBuilder | ||
128 | for (m : pair.value) { | ||
129 | multiplicityBuilder.add(1, m.match) | ||
130 | } | ||
131 | if (CostElementMatchers.isMulti(pair.key)) { | ||
132 | multiplicityBuilder.add(-count, type) | ||
133 | multiplicityBuilder.build.tightenUpperBound(0) | ||
134 | } else { | ||
135 | multiplicityBuilder.build.tightenUpperBound(count) | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | } \ No newline at end of file | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/MisalignedTurnoutObjectiveHint.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/MisalignedTurnoutObjectiveHint.xtend new file mode 100644 index 00000000..cb014dea --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/MisalignedTurnoutObjectiveHint.xtend | |||
@@ -0,0 +1,140 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilderFactory | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatch | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatchers | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint | ||
10 | import java.util.Collection | ||
11 | import java.util.Map | ||
12 | import modes3.Modes3Package | ||
13 | import modes3.queries.MisalignedTurnout_step_2 | ||
14 | import modes3.queries.MisalignedTurnout_step_3 | ||
15 | import modes3.queries.MisalignedTurnout_step_4 | ||
16 | import modes3.queries.MisalignedTurnout_step_5 | ||
17 | |||
18 | class MisalignedTurnoutObjectiveHint extends CostObjectiveHint { | ||
19 | val Type segmentType | ||
20 | val Type turnoutType | ||
21 | val Type trainType | ||
22 | |||
23 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
24 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
25 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
26 | turnoutType = ecore2LogicTrace.TypeofEClass(turnout) | ||
27 | trainType = ecore2LogicTrace.TypeofEClass(train) | ||
28 | } | ||
29 | |||
30 | override isExact() { | ||
31 | true | ||
32 | // false | ||
33 | } | ||
34 | |||
35 | override createPolyhedronExtensionOperator(Map<String, CostElementMatchers> costElementMatchers) { | ||
36 | val step2 = costElementMatchers.get(MisalignedTurnout_step_2.instance.fullyQualifiedName) | ||
37 | val step3 = costElementMatchers.get(MisalignedTurnout_step_3.instance.fullyQualifiedName) | ||
38 | val step4 = costElementMatchers.get(MisalignedTurnout_step_4.instance.fullyQualifiedName) | ||
39 | val step5 = costElementMatchers.get(MisalignedTurnout_step_5.instance.fullyQualifiedName); | ||
40 | |||
41 | [ | ||
42 | val objectiveBuilder = createBuilder | ||
43 | |||
44 | for (m : step2.matches) { | ||
45 | val dimension = getDimension(m.match) | ||
46 | objectiveBuilder.add(step2.weight, dimension) | ||
47 | dimension.tightenLowerBound(0) | ||
48 | if (m.multi) { | ||
49 | createBuilder.add(1, dimension).add(-1, turnoutType).build.assertEqualsTo(0) | ||
50 | } else { | ||
51 | dimension.tightenUpperBound(1) | ||
52 | if (m.must) { | ||
53 | dimension.tightenLowerBound(1) | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
58 | val step3Matches = step3.matches | ||
59 | for (m : step3Matches) { | ||
60 | val dimension = getDimension(m.match) | ||
61 | objectiveBuilder.add(step3.weight, dimension) | ||
62 | dimension.tightenLowerBound(0) | ||
63 | if (!m.multi) { | ||
64 | dimension.tightenUpperBound(1) | ||
65 | if (m.must) { | ||
66 | dimension.tightenLowerBound(1) | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | for (pair : step3Matches.groupBy[step2.projectMayMatch(match, 2)].entrySet) { | ||
71 | val multiplicityBuilder = createBuilder | ||
72 | for (m : pair.value) { | ||
73 | multiplicityBuilder.add(1, m.match) | ||
74 | } | ||
75 | multiplicityBuilder.add(-1, pair.key) | ||
76 | multiplicityBuilder.build.tightenUpperBound(0) | ||
77 | } | ||
78 | boundLimit(step3Matches, 2, turnoutType, 1) | ||
79 | boundLimit(step3Matches, 3, segmentType, 2) | ||
80 | |||
81 | val step4Matches = step4.matches | ||
82 | for (m : step4Matches) { | ||
83 | val dimension = getDimension(m.match) | ||
84 | objectiveBuilder.add(step4.weight, dimension) | ||
85 | dimension.tightenLowerBound(0) | ||
86 | if (!m.multi) { | ||
87 | dimension.tightenUpperBound(1) | ||
88 | if (m.must) { | ||
89 | dimension.tightenLowerBound(1) | ||
90 | } | ||
91 | } | ||
92 | createBuilder.add(1, m.match).add(-1, step3.projectMayMatch(m.match, 2, 3)).build.tightenUpperBound(0) | ||
93 | } | ||
94 | boundLimit(step4Matches, 2, turnoutType, 1) | ||
95 | boundLimit(step4Matches, 3, segmentType, 2) | ||
96 | |||
97 | val step5Matches = step5.matches | ||
98 | for (m : step5Matches) { | ||
99 | val dimension = getDimension(m.match) | ||
100 | objectiveBuilder.add(step5.weight, dimension) | ||
101 | dimension.tightenLowerBound(0) | ||
102 | if (!m.multi) { | ||
103 | dimension.tightenUpperBound(1) | ||
104 | if (m.must) { | ||
105 | dimension.tightenLowerBound(1) | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | for (pair : step5Matches.groupBy[step4.projectMayMatch(match, 2, 3)].entrySet) { | ||
110 | val multiplicityBuilder = createBuilder | ||
111 | for (m : pair.value) { | ||
112 | multiplicityBuilder.add(1, m.match) | ||
113 | } | ||
114 | multiplicityBuilder.add(-1, pair.key) | ||
115 | multiplicityBuilder.build.tightenUpperBound(0) | ||
116 | } | ||
117 | boundLimit(step5Matches, 2, turnoutType, 1) | ||
118 | boundLimit(step5Matches, 3, segmentType, 2) | ||
119 | boundLimit(step5Matches, 4, trainType, 2) | ||
120 | |||
121 | objectiveBuilder.buildWithBounds | ||
122 | ] | ||
123 | } | ||
124 | |||
125 | private static def boundLimit(extension ExtendedLinearExpressionBuilderFactory factory, | ||
126 | Collection<CostElementMatch> matches, int index, Type type, int count) { | ||
127 | for (pair : matches.groupBy[match.get(index)].entrySet) { | ||
128 | val multiplicityBuilder = createBuilder | ||
129 | for (m : pair.value) { | ||
130 | multiplicityBuilder.add(1, m.match) | ||
131 | } | ||
132 | if (CostElementMatchers.isMulti(pair.key)) { | ||
133 | multiplicityBuilder.add(-count, type) | ||
134 | multiplicityBuilder.build.tightenUpperBound(0) | ||
135 | } else { | ||
136 | multiplicityBuilder.build.tightenUpperBound(count) | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | } | ||
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..288a7692 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend | |||
@@ -0,0 +1,357 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import com.google.common.collect.ImmutableSet | ||
5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EReferenceMapper_RelationsOverTypes_Trace | ||
6 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
7 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2LogicConfiguration | ||
8 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
9 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EcoreMetamodelDescriptor | ||
10 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsFactory | ||
11 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsPackage | ||
12 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel | ||
13 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicProblemBuilder | ||
14 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguagePackage | ||
15 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition | ||
16 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage | ||
17 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult | ||
18 | import hu.bme.mit.inf.dslreasoner.logic2ecore.Logic2Ecore | ||
19 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic | ||
20 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2LogicConfiguration | ||
21 | import hu.bme.mit.inf.dslreasoner.viatra2logic.ViatraQuerySetDescriptor | ||
22 | import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.Viatra2LogicAnnotationsPackage | ||
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.TypeInferenceMethod | ||
24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorConstraints | ||
25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.PolyhedralScopePropagatorSolver | ||
26 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagatorStrategy | ||
27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.InstanceModel2Logic | ||
28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink | ||
29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | ||
30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | ||
31 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretation2Gml | ||
32 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveConfiguration | ||
33 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.CostObjectiveElementConfiguration | ||
34 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.StateCoderStrategy | ||
35 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasoner | ||
36 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration | ||
37 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation | ||
38 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind | ||
39 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold | ||
40 | import hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz.GraphvizVisualiser | ||
41 | import hu.bme.mit.inf.dslreasoner.workspace.FileSystemWorkspace | ||
42 | import java.util.List | ||
43 | import modes3.Modes3Factory | ||
44 | import modes3.Modes3Package | ||
45 | import modes3.queries.CloseTrains_step_2 | ||
46 | import modes3.queries.CloseTrains_step_3 | ||
47 | import modes3.queries.CloseTrains_step_4 | ||
48 | import modes3.queries.CloseTrains_step_5 | ||
49 | import modes3.queries.CloseTrains_step_6 | ||
50 | import modes3.queries.CloseTrains_step_7 | ||
51 | import modes3.queries.EndOfSiding_step_2 | ||
52 | import modes3.queries.EndOfSiding_step_3 | ||
53 | import modes3.queries.EndOfSiding_step_4 | ||
54 | import modes3.queries.EndOfSiding_step_5 | ||
55 | import modes3.queries.MisalignedTurnout_step_2 | ||
56 | import modes3.queries.MisalignedTurnout_step_3 | ||
57 | import modes3.queries.MisalignedTurnout_step_4 | ||
58 | import modes3.queries.MisalignedTurnout_step_5 | ||
59 | import modes3.queries.Modes3Queries | ||
60 | import modes3.queries.TrainLocations_step_2 | ||
61 | import modes3.queries.TrainLocations_step_3 | ||
62 | import org.eclipse.emf.ecore.EClass | ||
63 | import org.eclipse.emf.ecore.EObject | ||
64 | import org.eclipse.emf.ecore.resource.Resource | ||
65 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | ||
66 | import org.eclipse.viatra.query.patternlanguage.emf.EMFPatternLanguageStandaloneSetup | ||
67 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions | ||
68 | import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchEMFBackendFactory | ||
69 | import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory | ||
70 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
71 | |||
72 | @FinalFieldsConstructor | ||
73 | class 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 | } | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3TypeScopeHint.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3TypeScopeHint.xtend new file mode 100644 index 00000000..94e5eb08 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3TypeScopeHint.xtend | |||
@@ -0,0 +1,79 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeConstraintHint | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.LinearTypeExpressionBuilderFactory | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternGenerator | ||
10 | import java.util.Map | ||
11 | import modes3.Modes3Package | ||
12 | import modes3.queries.Adjacent | ||
13 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
14 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
15 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery | ||
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
17 | |||
18 | class Modes3TypeScopeHint implements LinearTypeConstraintHint { | ||
19 | static val TURNOUT_NEIGHBOR_COUNT = "turnoutNeighborCount" | ||
20 | |||
21 | val Type segmentType | ||
22 | val Type turnoutType | ||
23 | |||
24 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
25 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
26 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
27 | turnoutType = ecore2LogicTrace.TypeofEClass(turnout) | ||
28 | } | ||
29 | |||
30 | override getAdditionalPatterns(extension PatternGenerator patternGenerator, Map<String, PQuery> fqnToPQuery) { | ||
31 | ''' | ||
32 | pattern «TURNOUT_NEIGHBOR_COUNT»_helper(problem: LogicProblem, interpretation: PartialInterpretation, source: DefinedElement, target: DefinedElement) { | ||
33 | find interpretation(problem, interpretation); | ||
34 | find mustExist(problem, interpretation, source); | ||
35 | find mustExist(problem, interpretation, target); | ||
36 | «typeIndexer.referInstanceOf(turnoutType, Modality.MUST, "source")» | ||
37 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "target")» | ||
38 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["source", "target"], Modality.MUST, true, false)» | ||
39 | } | ||
40 | |||
41 | pattern «TURNOUT_NEIGHBOR_COUNT»(problem: LogicProblem, interpretation: PartialInterpretation, element: DefinedElement, N) { | ||
42 | find interpretation(problem, interpretation); | ||
43 | find mustExist(problem, interpretation, element); | ||
44 | «typeIndexer.referInstanceOf(turnoutType, Modality.MUST, "element")» | ||
45 | N == count find «TURNOUT_NEIGHBOR_COUNT»_helper(problem, interpretation, element, _); | ||
46 | } | ||
47 | ''' | ||
48 | } | ||
49 | |||
50 | override createConstraintUpdater(LinearTypeExpressionBuilderFactory builderFactory) { | ||
51 | val turnoutNeighborCountMatcher = builderFactory.createMatcher(TURNOUT_NEIGHBOR_COUNT) | ||
52 | val newNeighbors = builderFactory.createBuilder.add(1, segmentType).build | ||
53 | |||
54 | return [ partialInterpretation | | ||
55 | val requiredNeighbbors = turnoutNeighborCountMatcher.getRemainingCount(partialInterpretation, 3) | ||
56 | newNeighbors.tightenLowerBound(requiredNeighbbors) | ||
57 | ] | ||
58 | } | ||
59 | |||
60 | private static def <T extends IPatternMatch> getRemainingCount(ViatraQueryMatcher<T> matcher, | ||
61 | PartialInterpretation partialInterpretation, int capacity) { | ||
62 | val partialMatch = matcher.newEmptyMatch | ||
63 | partialMatch.set(0, partialInterpretation.problem) | ||
64 | partialMatch.set(1, partialInterpretation) | ||
65 | val iterator = matcher.streamAllMatches(partialMatch).iterator | ||
66 | var int max = 0 | ||
67 | while (iterator.hasNext) { | ||
68 | val match = iterator.next | ||
69 | val n = (match.get(3) as Integer).intValue | ||
70 | if (n < capacity) { | ||
71 | val required = capacity - n | ||
72 | if (max < required) { | ||
73 | max = required | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | max | ||
78 | } | ||
79 | } | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3UnitPropagationGenerator.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3UnitPropagationGenerator.xtend new file mode 100644 index 00000000..953a21d4 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3UnitPropagationGenerator.xtend | |||
@@ -0,0 +1,417 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.PatternGenerator | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.UnitPropagationPatternGenerator | ||
10 | import java.util.Map | ||
11 | import modes3.Modes3Package | ||
12 | import modes3.queries.Adjacent | ||
13 | import modes3.queries.Output | ||
14 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery | ||
15 | import org.eclipse.xtend2.lib.StringConcatenationClient | ||
16 | |||
17 | class Modes3UnitPropagationGenerator implements UnitPropagationPatternGenerator { | ||
18 | static val MUST_NOT_CONNECTED_TO = "mustNotConnectedTo" | ||
19 | static val MUST_NOT_STRAIGHT = "mustNotStraight" | ||
20 | static val MUST_NOT_DIVERGENT = "mustNotDivergent" | ||
21 | static val MUST_CONNECTED_TO = "mustConnectedTo" | ||
22 | static val MUST_STRAIGHT = "mustStraight" | ||
23 | static val MUST_DIVERGENT = "mustDivergent" | ||
24 | |||
25 | val Type segmentType | ||
26 | val Type simpleSegmentType | ||
27 | val Type turnoutType | ||
28 | val Relation connectedToRelation | ||
29 | val Relation straightRelation | ||
30 | val Relation divergentRelation | ||
31 | |||
32 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
33 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
34 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
35 | simpleSegmentType = ecore2LogicTrace.TypeofEClass(simpleSegment) | ||
36 | turnoutType = ecore2LogicTrace.TypeofEClass(turnout) | ||
37 | connectedToRelation = ecore2LogicTrace.relationOfReference(segment_ConnectedTo) | ||
38 | straightRelation = ecore2LogicTrace.relationOfReference(turnout_Straight) | ||
39 | divergentRelation = ecore2LogicTrace.relationOfReference(turnout_Divergent) | ||
40 | } | ||
41 | |||
42 | override getMustPatterns() { | ||
43 | #{ | ||
44 | connectedToRelation -> MUST_CONNECTED_TO, | ||
45 | straightRelation -> MUST_STRAIGHT, | ||
46 | divergentRelation -> MUST_DIVERGENT | ||
47 | } | ||
48 | } | ||
49 | |||
50 | override getMustNotPatterns() { | ||
51 | #{ | ||
52 | connectedToRelation -> MUST_NOT_CONNECTED_TO, | ||
53 | straightRelation -> MUST_NOT_STRAIGHT, | ||
54 | divergentRelation -> MUST_NOT_DIVERGENT | ||
55 | } | ||
56 | } | ||
57 | |||
58 | override getAdditionalPatterns(extension PatternGenerator generator, Map<String, PQuery> fqnToPQuery) { | ||
59 | val StringConcatenationClient parameters = ''' | ||
60 | problem: LogicProblem, interpretation: PartialInterpretation, | ||
61 | source: DefinedElement, target: DefinedElement | ||
62 | ''' | ||
63 | |||
64 | val StringConcatenationClient commonMustParameterConstraints = ''' | ||
65 | find interpretation(problem, interpretation); | ||
66 | find mustExist(problem, interpretation, source); | ||
67 | find mustExist(problem, interpretation, target); | ||
68 | ''' | ||
69 | |||
70 | val StringConcatenationClient commonMayParameterConstraints = ''' | ||
71 | find interpretation(problem, interpretation); | ||
72 | find mayExist(problem, interpretation, source); | ||
73 | find mayExist(problem, interpretation, target); | ||
74 | ''' | ||
75 | |||
76 | ''' | ||
77 | pattern mayInput(«parameters») { | ||
78 | «commonMayParameterConstraints» | ||
79 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
80 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["target", "source"], Modality.MAY, true, false)» | ||
81 | neg «referRelation(straightRelation, "target", "source", Modality.MUST, fqnToPQuery)» | ||
82 | neg «referRelation(straightRelation, "target", "source", Modality.MUST, fqnToPQuery)» | ||
83 | } | ||
84 | |||
85 | pattern multipleMayInput(problem: LogicProblem, interpretation: PartialInterpretation, | ||
86 | target: DefinedElement) { | ||
87 | find interpretation(problem, interpretation); | ||
88 | find mustExist(problem, interpretation, target); | ||
89 | find mayInput(problem, interpretaton, source1, target); | ||
90 | find mayInput(problem, interpretaton, source2, target); | ||
91 | neg find mustEquivalent(problem, interpretation, source1, source2); | ||
92 | } | ||
93 | |||
94 | pattern multipleMayStraight(problem: LogicProblem, interpretation: PartialInterpretation, | ||
95 | source: DefinedElement) { | ||
96 | find interpretation(problem, interpretation); | ||
97 | find mustExist(problem, interpretation, source); | ||
98 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
99 | «referRelation(straightRelation, "source", "target1", Modality.MAY, fqnToPQuery)» | ||
100 | «referRelation(straightRelation, "source", "target2", Modality.MAY, fqnToPQuery)» | ||
101 | neg find mustEquivalent(problem, interpretation, target1, target2); | ||
102 | } | ||
103 | |||
104 | pattern multipleMayDivergent(problem: LogicProblem, interpretation: PartialInterpretation, | ||
105 | source: DefinedElement) { | ||
106 | find interpretation(problem, interpretation); | ||
107 | find mustExist(problem, interpretation, source); | ||
108 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
109 | «referRelation(divergentRelation, "source", "target1", Modality.MAY, fqnToPQuery)» | ||
110 | «referRelation(divergentRelation, "source", "target2", Modality.MAY, fqnToPQuery)» | ||
111 | neg find mustEquivalent(problem, interpretation, target1, target2); | ||
112 | } | ||
113 | |||
114 | pattern «MUST_CONNECTED_TO»(«parameters») { | ||
115 | «commonMustParameterConstraints» | ||
116 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
117 | find mayInput(problem, interpretaton, source, target); | ||
118 | neg find multipleMayInput(problem, interpretaton, target); | ||
119 | «referRelation(connectedToRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
120 | neg «referRelation(connectedToRelation, "source", "target", Modality.MUST, fqnToPQuery)» | ||
121 | neg «referRelation(straightRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
122 | neg «referRelation(divergentRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
123 | } | ||
124 | |||
125 | pattern «MUST_STRAIGHT»(«parameters») { | ||
126 | «commonMustParameterConstraints» | ||
127 | neg «referRelation(straightRelation, "source", "_", Modality.MUST, fqnToPQuery)» | ||
128 | neg find multipleMayStraight(problem, interpretation, source); | ||
129 | «referRelation(straightRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
130 | neg «referRelation(straightRelation, "source", "target", Modality.MUST, fqnToPQuery)» | ||
131 | } or { | ||
132 | «commonMustParameterConstraints» | ||
133 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
134 | find mayInput(problem, interpretaton, source, target); | ||
135 | neg find multipleMayInput(problem, interpretaton, target); | ||
136 | neg «referRelation(connectedToRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
137 | «referRelation(straightRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
138 | neg «referRelation(straightRelation, "source", "target", Modality.MUST, fqnToPQuery)» | ||
139 | neg «referRelation(divergentRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
140 | } | ||
141 | |||
142 | pattern «MUST_DIVERGENT»(«parameters») { | ||
143 | «commonMustParameterConstraints» | ||
144 | neg «referRelation(divergentRelation, "source", "_", Modality.MUST, fqnToPQuery)» | ||
145 | neg find multipleMayDivergent(problem, interpretation, source); | ||
146 | «referRelation(divergentRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
147 | neg «referRelation(divergentRelation, "source", "target", Modality.MUST, fqnToPQuery)» | ||
148 | } or { | ||
149 | «commonMustParameterConstraints» | ||
150 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
151 | find mayInput(problem, interpretaton, source, target); | ||
152 | neg find multipleMayInput(problem, interpretaton, target); | ||
153 | neg «referRelation(connectedToRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
154 | neg «referRelation(straightRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
155 | «referRelation(divergentRelation, "source", "target", Modality.MAY, fqnToPQuery)» | ||
156 | neg «referRelation(divergentRelation, "source", "target", Modality.MUST, fqnToPQuery)» | ||
157 | } | ||
158 | |||
159 | pattern turnoutOutput_must_to_true_by_straight(«parameters», T : DefinedElement, S : DefinedElement) { | ||
160 | «commonMayParameterConstraints» | ||
161 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
162 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
163 | T == source; | ||
164 | S == target; | ||
165 | } | ||
166 | |||
167 | pattern turnoutOutput_must_to_true_by_divergent(«parameters», T : DefinedElement, S : DefinedElement) { | ||
168 | «commonMayParameterConstraints» | ||
169 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
170 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
171 | T == source; | ||
172 | S == target; | ||
173 | } | ||
174 | |||
175 | pattern output_must_to_true_by_connectedTo(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
176 | «commonMayParameterConstraints» | ||
177 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "source")» | ||
178 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
179 | S1 == source; | ||
180 | S2 == target; | ||
181 | } | ||
182 | |||
183 | pattern output_must_to_true_by_straight(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
184 | find turnoutOutput_must_to_true_by_straight(problem, interpretation, source, target, S1, S2); | ||
185 | } | ||
186 | |||
187 | pattern output_must_to_true_by_divergent(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
188 | find turnoutOutput_must_to_true_by_divergent(problem, interpretation, source, target, S1, S2); | ||
189 | } | ||
190 | |||
191 | pattern adjacent_must_to_true_by_connectedTo(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
192 | find output_must_to_true_by_connectedTo(problem, interpretation, source, target, S1, S2); | ||
193 | } | ||
194 | |||
195 | pattern adjacent_must_to_true_by_straight(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
196 | find output_must_to_true_by_straight(problem, interpretation, source, target, S1, S2); | ||
197 | } or { | ||
198 | find turnoutOutput_must_to_true_by_straight(problem, interpretation, source, target, S2, S1); | ||
199 | } | ||
200 | |||
201 | pattern adjacent_must_to_true_by_divergent(«parameters», S1 : DefinedElement, S2 : DefinedElement) { | ||
202 | find output_must_to_true_by_divergent(problem, interpretation, source, target, S1, S2); | ||
203 | } or { | ||
204 | find turnoutOutput_must_to_true_by_divergent(problem, interpretation, source, target, S2, S1); | ||
205 | } | ||
206 | |||
207 | pattern connectedToReflexive_must_to_true_by_connectedTo(«parameters», S : DefinedElement) { | ||
208 | find mustExist(problem, interpretation, source); | ||
209 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "source")» | ||
210 | S == source; | ||
211 | S == target; | ||
212 | } | ||
213 | |||
214 | pattern outputReflexive_must_to_true_by_straight(«parameters», T : DefinedElement) { | ||
215 | find turnoutOutput_must_to_true_by_straight(problem, interpretation, source, target, T, T); | ||
216 | } | ||
217 | |||
218 | pattern outputReflexive_must_to_true_by_divergent(«parameters», T : DefinedElement) { | ||
219 | find turnoutOutput_must_to_true_by_divergent(problem, interpretation, source, target, T, T); | ||
220 | } | ||
221 | |||
222 | pattern turnoutOutputsAreSame_must_to_true_by_straight(«parameters», T : DefinedElement) { | ||
223 | «commonMayParameterConstraints» | ||
224 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
225 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
226 | T == source; | ||
227 | S == target; | ||
228 | «referRelation(divergentRelation, "T", "S", Modality.MUST, fqnToPQuery)» | ||
229 | } | ||
230 | |||
231 | pattern turnoutOutputsAreSame_must_to_true_by_divergent(«parameters», T : DefinedElement) { | ||
232 | «commonMayParameterConstraints» | ||
233 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
234 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
235 | T == source; | ||
236 | S == target; | ||
237 | «referRelation(straightRelation, "T", "S", Modality.MUST, fqnToPQuery)» | ||
238 | } | ||
239 | |||
240 | pattern tooManyInputsOfSegment_must_to_true_by_connectedTo(«parameters», S : DefinedElement) { | ||
241 | find mustExist(problem, interpretation, S); | ||
242 | «typeIndexer.referInstanceOf(simpleSegmentType, Modality.MUST, "S")» | ||
243 | find output_must_to_true_by_connectedTo(problem, interpretation, source, target, I1, S); | ||
244 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
245 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
246 | I1 != I2; | ||
247 | I1 != I3; | ||
248 | I2 != I3; | ||
249 | } | ||
250 | |||
251 | pattern tooManyInputsOfSegment_must_to_true_by_straight(«parameters», S : DefinedElement) { | ||
252 | find mustExist(problem, interpretation, S); | ||
253 | «typeIndexer.referInstanceOf(simpleSegmentType, Modality.MUST, "S")» | ||
254 | find output_must_to_true_by_straight(problem, interpretation, source, target, I1, S); | ||
255 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
256 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
257 | I1 != I2; | ||
258 | I1 != I3; | ||
259 | I2 != I3; | ||
260 | } | ||
261 | |||
262 | pattern tooManyInputsOfSegment_must_to_true_by_divergent(«parameters», S : DefinedElement) { | ||
263 | find mustExist(problem, interpretation, S); | ||
264 | «typeIndexer.referInstanceOf(simpleSegmentType, Modality.MUST, "S")» | ||
265 | find output_must_to_true_by_divergent(problem, interpretation, source, target, I1, S); | ||
266 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
267 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Output.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
268 | I1 != I2; | ||
269 | I1 != I3; | ||
270 | I2 != I3; | ||
271 | } | ||
272 | |||
273 | pattern turnoutConnectedToBothOutputs_must_to_true_by_connectedTo(«parameters», T : DefinedElement) { | ||
274 | «commonMayParameterConstraints» | ||
275 | find mustExist(problem, interpretation, Straight); | ||
276 | find mustExist(problem, interpretation, Divergent); | ||
277 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
278 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
279 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Straight")» | ||
280 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Divergent")» | ||
281 | «referRelation(straightRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
282 | «referRelation(divergentRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
283 | T == source; | ||
284 | Straight == target; | ||
285 | «referRelation(connectedToRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
286 | } or { | ||
287 | «commonMayParameterConstraints» | ||
288 | find mustExist(problem, interpretation, Straight); | ||
289 | find mustExist(problem, interpretation, Divergent); | ||
290 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
291 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
292 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Straight")» | ||
293 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Divergent")» | ||
294 | «referRelation(straightRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
295 | «referRelation(divergentRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
296 | «referRelation(connectedToRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
297 | T == source; | ||
298 | Straight == target; | ||
299 | } | ||
300 | |||
301 | pattern turnoutConnectedToBothOutputs_must_to_true_by_straight(«parameters», T : DefinedElement) { | ||
302 | «commonMayParameterConstraints» | ||
303 | find mustExist(problem, interpretation, Straight); | ||
304 | find mustExist(problem, interpretation, Divergent); | ||
305 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
306 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
307 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Straight")» | ||
308 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Divergent")» | ||
309 | T == source; | ||
310 | Straight == target; | ||
311 | «referRelation(divergentRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
312 | «referRelation(connectedToRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
313 | «referRelation(connectedToRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
314 | } | ||
315 | |||
316 | pattern turnoutConnectedToBothOutputs_must_to_true_by_divergent(«parameters», T : DefinedElement) { | ||
317 | «commonMayParameterConstraints» | ||
318 | find mustExist(problem, interpretation, Straight); | ||
319 | find mustExist(problem, interpretation, Divergent); | ||
320 | «typeIndexer.referInstanceOf(turnoutType, Modality.MAY, "source")» | ||
321 | «typeIndexer.referInstanceOf(segmentType, Modality.MAY, "target")» | ||
322 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Straight")» | ||
323 | «typeIndexer.referInstanceOf(segmentType, Modality.MUST, "Divergent")» | ||
324 | «referRelation(straightRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
325 | T == source; | ||
326 | Divergent == target; | ||
327 | «referRelation(connectedToRelation, "T", "Straight", Modality.MUST, fqnToPQuery)» | ||
328 | «referRelation(connectedToRelation, "T", "Divergent", Modality.MUST, fqnToPQuery)» | ||
329 | } | ||
330 | |||
331 | pattern tooManyInputsOfTurnout_must_to_true_by_connectedTo(«parameters», T : DefinedElement) { | ||
332 | find mustExist(problem, interpretation, S); | ||
333 | «typeIndexer.referInstanceOf(turnoutType, Modality.MUST, "S")» | ||
334 | find adjacent_must_to_true_by_connectedTo(problem, interpretation, source, target, I1, S); | ||
335 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
336 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
337 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I4", "S"], Modality.MUST, true, false)» | ||
338 | I1 != I2; | ||
339 | I1 != I3; | ||
340 | I1 != I4; | ||
341 | I2 != I3; | ||
342 | I2 != I4; | ||
343 | I3 != I4; | ||
344 | } | ||
345 | |||
346 | pattern tooManyInputsOfTurnout_must_to_true_by_straight(«parameters», T : DefinedElement) { | ||
347 | find mustExist(problem, interpretation, S); | ||
348 | «typeIndexer.referInstanceOf(turnoutType, Modality.MUST, "S")» | ||
349 | find adjacent_must_to_true_by_straight(problem, interpretation, source, target, I1, S); | ||
350 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
351 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
352 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I4", "S"], Modality.MUST, true, false)» | ||
353 | I1 != I2; | ||
354 | I1 != I3; | ||
355 | I1 != I4; | ||
356 | I2 != I3; | ||
357 | I2 != I4; | ||
358 | I3 != I4; | ||
359 | } | ||
360 | |||
361 | pattern tooManyInputsOfTurnout_must_to_true_by_divergent(«parameters», T : DefinedElement) { | ||
362 | find mustExist(problem, interpretation, S); | ||
363 | «typeIndexer.referInstanceOf(turnoutType, Modality.MUST, "S")» | ||
364 | find adjacent_must_to_true_by_divergent(problem, interpretation, source, target, I1, S); | ||
365 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I2", "S"], Modality.MUST, true, false)» | ||
366 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I3", "S"], Modality.MUST, true, false)» | ||
367 | «relationDefinitionIndexer.referPattern(fqnToPQuery.get(Adjacent.instance.fullyQualifiedName), #["I4", "S"], Modality.MUST, true, false)» | ||
368 | I1 != I2; | ||
369 | I1 != I3; | ||
370 | I1 != I4; | ||
371 | I2 != I3; | ||
372 | I2 != I4; | ||
373 | I3 != I4; | ||
374 | } | ||
375 | |||
376 | pattern «MUST_NOT_CONNECTED_TO»_helper(«parameters») { | ||
377 | find connectedToReflexive_must_to_true_by_connectedTo(problem, interpretation, source, target, _); | ||
378 | } or { | ||
379 | find tooManyInputsOfSegment_must_to_true_by_connectedTo(problem, interpretation, source, target, _); | ||
380 | } or { | ||
381 | find turnoutConnectedToBothOutputs_must_to_true_by_connectedTo(problem, interpretation, source, target, _); | ||
382 | } or { | ||
383 | find tooManyInputsOfTurnout_must_to_true_by_connectedTo(problem, interpretation, source, target, _); | ||
384 | } | ||
385 | |||
386 | pattern «MUST_NOT_CONNECTED_TO»(«parameters») { | ||
387 | find «MUST_NOT_CONNECTED_TO»_helper(problem, interpretation, source, target); | ||
388 | } or { | ||
389 | find «MUST_NOT_CONNECTED_TO»_helper(problem, interpretation, target, source); | ||
390 | } | ||
391 | |||
392 | pattern «MUST_NOT_STRAIGHT»(«parameters») { | ||
393 | find outputReflexive_must_to_true_by_straight(problem, interpretation, source, target, _); | ||
394 | } or { | ||
395 | find turnoutOutputsAreSame_must_to_true_by_straight(problem, interpretation, source, target, _); | ||
396 | } or { | ||
397 | find tooManyInputsOfSegment_must_to_true_by_straight(problem, interpretation, source, target, _); | ||
398 | } or { | ||
399 | find turnoutConnectedToBothOutputs_must_to_true_by_straight(problem, interpretation, source, target, _); | ||
400 | } or { | ||
401 | find tooManyInputsOfTurnout_must_to_true_by_straight(problem, interpretation, source, target, _); | ||
402 | } | ||
403 | |||
404 | pattern «MUST_NOT_DIVERGENT»(«parameters») { | ||
405 | find outputReflexive_must_to_true_by_divergent(problem, interpretation, source, target, _); | ||
406 | } or { | ||
407 | find turnoutOutputsAreSame_must_to_true_by_divergent(problem, interpretation, source, target, _); | ||
408 | } or { | ||
409 | find tooManyInputsOfSegment_must_to_true_by_divergent(problem, interpretation, source, target, _); | ||
410 | } or { | ||
411 | find turnoutConnectedToBothOutputs_must_to_true_by_divergent(problem, interpretation, source, target, _); | ||
412 | } or { | ||
413 | find tooManyInputsOfTurnout_must_to_true_by_divergent(problem, interpretation, source, target, _); | ||
414 | } | ||
415 | ''' | ||
416 | } | ||
417 | } | ||
diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/TrainLocationsObjectiveHint.xtend b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/TrainLocationsObjectiveHint.xtend new file mode 100644 index 00000000..cc2d7925 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/TrainLocationsObjectiveHint.xtend | |||
@@ -0,0 +1,85 @@ | |||
1 | package modes3.run | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ExtendedLinearExpressionBuilderFactory | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatch | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostElementMatchers | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CostObjectiveHint | ||
10 | import java.util.Collection | ||
11 | import java.util.Map | ||
12 | import modes3.Modes3Package | ||
13 | import modes3.queries.TrainLocations_step_2 | ||
14 | import modes3.queries.TrainLocations_step_3 | ||
15 | |||
16 | class TrainLocationsObjectiveHint extends CostObjectiveHint { | ||
17 | val Type segmentType | ||
18 | val Type trainType | ||
19 | |||
20 | new(extension Ecore2Logic ecore2Logic, Ecore2Logic_Trace ecore2LogicTrace) { | ||
21 | extension val Modes3Package = Modes3Package.eINSTANCE | ||
22 | segmentType = ecore2LogicTrace.TypeofEClass(segment) | ||
23 | trainType = ecore2LogicTrace.TypeofEClass(train) | ||
24 | } | ||
25 | |||
26 | override isExact() { | ||
27 | true | ||
28 | } | ||
29 | |||
30 | override createPolyhedronExtensionOperator(Map<String, CostElementMatchers> costElementMatchers) { | ||
31 | val step2 = costElementMatchers.get(TrainLocations_step_2.instance.fullyQualifiedName) | ||
32 | val step3 = costElementMatchers.get(TrainLocations_step_3.instance.fullyQualifiedName); | ||
33 | |||
34 | [ | ||
35 | val objectiveBuilder = createBuilder | ||
36 | |||
37 | for (m : step2.matches) { | ||
38 | val dimension = getDimension(m.match) | ||
39 | objectiveBuilder.add(step2.weight, dimension) | ||
40 | dimension.tightenLowerBound(0) | ||
41 | if (m.multi) { | ||
42 | createBuilder.add(1, dimension).add(-1, trainType).build.assertEqualsTo(0) | ||
43 | } else { | ||
44 | dimension.tightenUpperBound(1) | ||
45 | if (m.must) { | ||
46 | dimension.tightenLowerBound(1) | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | val step3Matches = step3.matches | ||
52 | for (m : step3Matches) { | ||
53 | val dimension = getDimension(m.match) | ||
54 | objectiveBuilder.add(step3.weight, dimension) | ||
55 | dimension.tightenLowerBound(0) | ||
56 | if (!m.multi) { | ||
57 | dimension.tightenUpperBound(1) | ||
58 | if (m.must) { | ||
59 | dimension.tightenLowerBound(1) | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | boundLimit(step3Matches, 2, trainType, 1) | ||
64 | boundLimit(step3Matches, 3, segmentType, 1) | ||
65 | |||
66 | objectiveBuilder.buildWithBounds | ||
67 | ] | ||
68 | } | ||
69 | |||
70 | private static def boundLimit(extension ExtendedLinearExpressionBuilderFactory factory, | ||
71 | Collection<CostElementMatch> matches, int index, Type type, int count) { | ||
72 | for (pair : matches.groupBy[match.get(index)].entrySet) { | ||
73 | val multiplicityBuilder = createBuilder | ||
74 | for (m : pair.value) { | ||
75 | multiplicityBuilder.add(1, m.match) | ||
76 | } | ||
77 | if (CostElementMatchers.isMulti(pair.key)) { | ||
78 | multiplicityBuilder.add(-count, type) | ||
79 | multiplicityBuilder.build.tightenUpperBound(0) | ||
80 | } else { | ||
81 | multiplicityBuilder.build.tightenUpperBound(count) | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } \ No newline at end of file | ||