diff options
author | 2020-11-02 02:02:40 +0100 | |
---|---|---|
committer | 2020-11-02 02:02:40 +0100 | |
commit | f06427cd7375551582461f91b3458339a8227f9b (patch) | |
tree | 97bc6ec85f4c384e5080a6611b492caf460b6ce9 /Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run | |
parent | Must unit propagation (diff) | |
download | VIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.tar.gz VIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.tar.zst VIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.zip |
Optimizing generator with linear objective functions
Diffstat (limited to 'Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run')
5 files changed, 724 insertions, 30 deletions
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 index fac7c496..613cb3e4 100644 --- a/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/src/modes3/run/Modes3ModelGenerator.xtend | |||
@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableSet | |||
5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EReferenceMapper_RelationsOverTypes_Trace | 5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EReferenceMapper_RelationsOverTypes_Trace |
6 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic | 6 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic |
7 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2LogicConfiguration | 7 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2LogicConfiguration |
8 | import hu.bme.mit.inf.dslreasoner.ecore2logic.Ecore2Logic_Trace | ||
8 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EcoreMetamodelDescriptor | 9 | import hu.bme.mit.inf.dslreasoner.ecore2logic.EcoreMetamodelDescriptor |
9 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsFactory | 10 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsFactory |
10 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsPackage | 11 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsPackage |
@@ -14,6 +15,7 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguagePackage | |||
14 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition | 15 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeDefinition |
15 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage | 16 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicproblemPackage |
16 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult | 17 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult |
18 | import hu.bme.mit.inf.dslreasoner.logic2ecore.Logic2Ecore | ||
17 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic | 19 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2Logic |
18 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2LogicConfiguration | 20 | import hu.bme.mit.inf.dslreasoner.viatra2logic.Viatra2LogicConfiguration |
19 | import hu.bme.mit.inf.dslreasoner.viatra2logic.ViatraQuerySetDescriptor | 21 | import hu.bme.mit.inf.dslreasoner.viatra2logic.ViatraQuerySetDescriptor |
@@ -25,18 +27,38 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePro | |||
25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.InstanceModel2Logic | 27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.InstanceModel2Logic |
26 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink | 28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BinaryElementRelationLink |
27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | 29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation |
28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage | 30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage |
30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretation2Gml | 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 | ||
31 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.StateCoderStrategy | 34 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.StateCoderStrategy |
32 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasoner | 35 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasoner |
33 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration | 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 | ||
34 | import hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz.GraphvizVisualiser | 40 | import hu.bme.mit.inf.dslreasoner.visualisation.pi2graphviz.GraphvizVisualiser |
35 | import hu.bme.mit.inf.dslreasoner.workspace.FileSystemWorkspace | 41 | import hu.bme.mit.inf.dslreasoner.workspace.FileSystemWorkspace |
36 | import java.util.List | 42 | import java.util.List |
37 | import modes3.Modes3Factory | 43 | import modes3.Modes3Factory |
38 | import modes3.Modes3Package | 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 | ||
39 | import modes3.queries.Modes3Queries | 59 | import modes3.queries.Modes3Queries |
60 | import modes3.queries.TrainLocations_step_2 | ||
61 | import modes3.queries.TrainLocations_step_3 | ||
40 | import org.eclipse.emf.ecore.EClass | 62 | import org.eclipse.emf.ecore.EClass |
41 | import org.eclipse.emf.ecore.EObject | 63 | import org.eclipse.emf.ecore.EObject |
42 | import org.eclipse.emf.ecore.resource.Resource | 64 | import org.eclipse.emf.ecore.resource.Resource |
@@ -92,17 +114,21 @@ class Modes3ModelGenerator { | |||
92 | minNewElements = modelSize | 114 | minNewElements = modelSize |
93 | maxNewElements = modelSize | 115 | maxNewElements = modelSize |
94 | minNewElementsByType => [ | 116 | minNewElementsByType => [ |
95 | // put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.turnout), 5) | 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) | ||
96 | ] | 120 | ] |
97 | maxNewElementsByType => [ | 121 | maxNewElementsByType => [ |
98 | put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.train), 5) | 122 | put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.train), modelSize / 5) |
99 | put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.turnout), 5) | 123 | put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.turnout), modelSize / 5) |
124 | put(ecore2Logic.TypeofEClass(metamodelLogic.trace, Modes3Package.eINSTANCE.simpleSegment), 3 * modelSize / 5) | ||
100 | ] | 125 | ] |
101 | ] | 126 | ] |
102 | solutionScope => [ | 127 | solutionScope => [ |
103 | numberOfRequiredSolutions = 1 | 128 | numberOfRequiredSolutions = 1 |
104 | ] | 129 | ] |
105 | scopeWeight = 5 | 130 | costObjectives += getObjective(ecore2Logic, metamodelLogic.trace) |
131 | scopeWeight = 6 | ||
106 | nameNewElements = false | 132 | nameNewElements = false |
107 | typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis | 133 | typeInferenceMethod = TypeInferenceMethod.PreliminaryAnalysis |
108 | stateCoderStrategy = StateCoderStrategy.PairwiseNeighbourhood | 134 | stateCoderStrategy = StateCoderStrategy.PairwiseNeighbourhood |
@@ -121,47 +147,60 @@ class Modes3ModelGenerator { | |||
121 | val solution = solver.solve(logic.output, config, workspace) | 147 | val solution = solver.solve(logic.output, config, workspace) |
122 | if (solution instanceof ModelResult) { | 148 | if (solution instanceof ModelResult) { |
123 | println("Saving generated solutions") | 149 | println("Saving generated solutions") |
124 | val representations = solution.representation | 150 | val logic2Ecore = new Logic2Ecore(ecore2Logic) |
125 | for (representationIndex : 0 ..< representations.size) { | 151 | val interpretations = solver.getInterpretations(solution) |
126 | val representation = representations.get(representationIndex) | 152 | for (representationIndex : 0 ..< interpretations.size) { |
153 | val interpretation = interpretations.get(representationIndex) | ||
127 | val representationNumber = representationIndex + 1 | 154 | val representationNumber = representationIndex + 1 |
128 | if (representation instanceof PartialInterpretation) { | 155 | if (interpretation instanceof PartialModelAsLogicInterpretation) { |
156 | val representation = interpretation.partialInterpretation | ||
129 | workspace.writeModel(representation, '''solution«representationNumber».partialinterpretation''') | 157 | workspace.writeModel(representation, '''solution«representationNumber».partialinterpretation''') |
130 | val partialInterpretation2GML = new PartialInterpretation2Gml | 158 | val partialInterpretation2GML = new PartialInterpretation2Gml |
131 | val gml = partialInterpretation2GML.transform(representation) | 159 | val gml = partialInterpretation2GML.transform(representation) |
132 | workspace.writeText('''solution«representationNumber».gml''', gml) | 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''') | ||
133 | if (representation.newElements.size < 160) { | 173 | if (representation.newElements.size < 160) { |
134 | if (representation instanceof PartialInterpretation) { | 174 | val rootType = (representation.problem.types.findFirst [ |
135 | val rootType = (representation.problem.types.findFirst [ | 175 | name == "Modes3ModelRoot class DefinedPart" |
136 | name == "Modes3ModelRoot class DefinedPart" | 176 | ] as TypeDefinition) |
137 | ] as TypeDefinition) | 177 | val rootIntepretation = representation.partialtypeinterpratation.filter( |
138 | val rootIntepretation = representation.partialtypeinterpratation.filter( | 178 | PartialComplexTypeInterpretation).findFirst [ |
139 | PartialComplexTypeInterpretation).findFirst [ | 179 | interpretationOf.name == "Modes3ModelRoot class" |
140 | 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 | } | ||
141 | ] | 191 | ] |
142 | rootIntepretation.elements.removeAll(rootType.elements) | ||
143 | representation.problem.elements.removeAll(rootType.elements) | ||
144 | for (relationInterpretation : representation.partialrelationinterpretation) { | ||
145 | relationInterpretation.relationlinks.removeIf [ link | | ||
146 | if (link instanceof BinaryElementRelationLink) { | ||
147 | rootType.elements.contains(link.param1) || rootType.elements.contains(link.param2) | ||
148 | } else { | ||
149 | false | ||
150 | } | ||
151 | ] | ||
152 | } | ||
153 | rootType.elements.clear | ||
154 | } | 192 | } |
193 | rootType.elements.clear | ||
155 | val visualiser = new GraphvizVisualiser | 194 | val visualiser = new GraphvizVisualiser |
156 | val visualisation = visualiser.visualiseConcretization(representation) | 195 | val visualisation = visualiser.visualiseConcretization(representation) |
157 | visualisation.writeToFile(workspace, '''solution«representationNumber».png''') | 196 | visualisation.writeToFile(workspace, '''solution«representationNumber».png''') |
158 | } | 197 | } |
159 | } else { | 198 | } else { |
160 | workspace.writeText('''solution«representationNumber».txt''', representation.toString) | 199 | workspace.writeText('''solution«representationNumber».txt''', interpretation.toString) |
161 | } | 200 | } |
162 | } | 201 | } |
163 | } else { | 202 | } else { |
164 | println("Failed to solver problem") | 203 | println("Failed to solve problem") |
165 | val partial = logic.output | 204 | val partial = logic.output |
166 | workspace.writeModel(partial, "solution.partialinterpretation") | 205 | workspace.writeModel(partial, "solution.partialinterpretation") |
167 | } | 206 | } |
@@ -198,6 +237,94 @@ class Modes3ModelGenerator { | |||
198 | ) | 237 | ) |
199 | } | 238 | } |
200 | 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 | |||
201 | def static init() { | 328 | def static init() { |
202 | EMFPatternLanguageStandaloneSetup.doSetup | 329 | EMFPatternLanguageStandaloneSetup.doSetup |
203 | ViatraQueryEngineOptions.setSystemDefaultBackends(ReteBackendFactory.INSTANCE, ReteBackendFactory.INSTANCE, | 330 | ViatraQueryEngineOptions.setSystemDefaultBackends(ReteBackendFactory.INSTANCE, ReteBackendFactory.INSTANCE, |
@@ -223,6 +350,8 @@ class Modes3ModelGenerator { | |||
223 | 350 | ||
224 | private static enum MonitoringQuery { | 351 | private static enum MonitoringQuery { |
225 | closeTrains, | 352 | closeTrains, |
353 | trainLocations, | ||
354 | endOfSiding, | ||
226 | misalignedTurnout | 355 | misalignedTurnout |
227 | } | 356 | } |
228 | } | 357 | } |
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 | ||