1 | //------------------------------------------------------------------------------------------------- |
---|
2 | // Module : $RCSfile: DefaultIterationDetectionRule.java,v $ |
---|
3 | // Version : $Revision: 0.0 $ $Author: patrick $ $Date: 19.02.2012 $ |
---|
4 | // Project : TaskTreeCreator |
---|
5 | // Creation : 2012 by patrick |
---|
6 | // Copyright : Patrick Harms, 2012 |
---|
7 | //------------------------------------------------------------------------------------------------- |
---|
8 | package de.ugoe.cs.quest.tasktrees.temporalrelation; |
---|
9 | |
---|
10 | import java.util.ArrayList; |
---|
11 | import java.util.List; |
---|
12 | |
---|
13 | import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEquality; |
---|
14 | import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager; |
---|
15 | import de.ugoe.cs.quest.tasktrees.treeifc.Iteration; |
---|
16 | import de.ugoe.cs.quest.tasktrees.treeifc.Selection; |
---|
17 | import de.ugoe.cs.quest.tasktrees.treeifc.Sequence; |
---|
18 | import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder; |
---|
19 | import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode; |
---|
20 | import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory; |
---|
21 | |
---|
22 | //------------------------------------------------------------------------------------------------- |
---|
23 | /** |
---|
24 | * TODO comment |
---|
25 | * |
---|
26 | * @version $Revision: $ $Date: 19.02.2012$ |
---|
27 | * @author 2012, last modified by $Author: patrick$ |
---|
28 | */ |
---|
29 | //------------------------------------------------------------------------------------------------- |
---|
30 | public class DefaultIterationDetectionRule implements TemporalRelationshipRule |
---|
31 | { |
---|
32 | /** */ |
---|
33 | private NodeEqualityRuleManager mNodeEqualityRuleManager; |
---|
34 | |
---|
35 | //----------------------------------------------------------------------------------------------- |
---|
36 | /** |
---|
37 | * TODO: comment |
---|
38 | * |
---|
39 | */ |
---|
40 | //----------------------------------------------------------------------------------------------- |
---|
41 | DefaultIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager) |
---|
42 | { |
---|
43 | super(); |
---|
44 | mNodeEqualityRuleManager = nodeEqualityRuleManager; |
---|
45 | } |
---|
46 | |
---|
47 | //----------------------------------------------------------------------------------------------- |
---|
48 | /* (non-Javadoc) |
---|
49 | * @see TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory) |
---|
50 | */ |
---|
51 | //----------------------------------------------------------------------------------------------- |
---|
52 | @Override |
---|
53 | public RuleApplicationResult apply(TaskTreeNode parent, |
---|
54 | TaskTreeBuilder treeBuilder, |
---|
55 | TaskTreeNodeFactory nodeFactory, |
---|
56 | boolean finalize) |
---|
57 | { |
---|
58 | if (!(parent instanceof Sequence)) |
---|
59 | { |
---|
60 | return null; |
---|
61 | } |
---|
62 | |
---|
63 | // parent must already have at least 2 children |
---|
64 | if ((parent.getChildren() == null) || (parent.getChildren().size() < 2)) |
---|
65 | { |
---|
66 | return null; |
---|
67 | } |
---|
68 | |
---|
69 | // iterations represent as a list of nodes that splits up in several equal sublists. If |
---|
70 | // the remaining nodes also start an equal sublist, then the iteration may not be completed |
---|
71 | // yet. So wait for further interactions to only identify completed iterations. |
---|
72 | |
---|
73 | // to find longer iterations first, start with long sequences |
---|
74 | for (int end = parent.getChildren().size() - 1; end > 0; end--) |
---|
75 | { |
---|
76 | for (int start = 0; start < end; start++) |
---|
77 | { |
---|
78 | List<TaskTreeNode[]> equalVariants = |
---|
79 | getEqualSublistVariantsInBoundaries(parent, start, end); |
---|
80 | |
---|
81 | if (equalVariants != null) |
---|
82 | { |
---|
83 | if (!finalize) |
---|
84 | { |
---|
85 | // check, if the iteration may go on. This may be the case, if the detected iteration |
---|
86 | // finishes with the last child of the parent, or if the remaining children, which were |
---|
87 | // not identified as part of the iteration, start a further occurrence of the iteration |
---|
88 | if (end == (parent.getChildren().size() - 1)) |
---|
89 | { |
---|
90 | RuleApplicationResult result = new RuleApplicationResult(); |
---|
91 | result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); |
---|
92 | return result; |
---|
93 | } |
---|
94 | |
---|
95 | boolean allNodesEqual = true; |
---|
96 | for (int i = 0; ((allNodesEqual) && (i < equalVariants.get(0).length)); i++) |
---|
97 | { |
---|
98 | if ((end + i + 1) >= parent.getChildren().size()) |
---|
99 | { |
---|
100 | break; |
---|
101 | } |
---|
102 | |
---|
103 | NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules |
---|
104 | (equalVariants.get(0)[i], parent.getChildren().get(end + i + 1)); |
---|
105 | |
---|
106 | allNodesEqual &= |
---|
107 | nodeEquality.getStructuralEquality() || nodeEquality.getSemanticalEquality(); |
---|
108 | } |
---|
109 | |
---|
110 | if (allNodesEqual) |
---|
111 | { |
---|
112 | RuleApplicationResult result = new RuleApplicationResult(); |
---|
113 | result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FEASIBLE); |
---|
114 | return result; |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | RuleApplicationResult result = new RuleApplicationResult(); |
---|
119 | Iteration newIteration = nodeFactory.createNewIteration(); |
---|
120 | result.addNewlyCreatedParentNode(newIteration); |
---|
121 | |
---|
122 | if (equalVariants.size() == 1) |
---|
123 | { |
---|
124 | // all children are the same. Create an iteration of this child |
---|
125 | if (equalVariants.get(0).length == 1) |
---|
126 | { |
---|
127 | // all children are the same. Create an iteration of this child |
---|
128 | treeBuilder.setChild(newIteration, equalVariants.get(0)[0]); |
---|
129 | } |
---|
130 | else |
---|
131 | { |
---|
132 | // there was an iteration of structurally equal sequences |
---|
133 | Sequence sequence = nodeFactory.createNewSequence(); |
---|
134 | result.addNewlyCreatedParentNode(sequence); |
---|
135 | |
---|
136 | for (TaskTreeNode node : equalVariants.get(0)) |
---|
137 | { |
---|
138 | treeBuilder.addChild(sequence, node); |
---|
139 | } |
---|
140 | |
---|
141 | treeBuilder.setChild(newIteration, sequence); |
---|
142 | } |
---|
143 | } |
---|
144 | else |
---|
145 | { |
---|
146 | // there are distinct variants of semantically equal subsequences or children --> |
---|
147 | // create an iterated selection |
---|
148 | Selection selection = nodeFactory.createNewSelection(); |
---|
149 | result.addNewlyCreatedParentNode(selection); |
---|
150 | |
---|
151 | for (TaskTreeNode[] variant : equalVariants) |
---|
152 | { |
---|
153 | if (variant.length == 1) |
---|
154 | { |
---|
155 | treeBuilder.addChild(selection, variant[0]); |
---|
156 | } |
---|
157 | else |
---|
158 | { |
---|
159 | Sequence sequence = nodeFactory.createNewSequence(); |
---|
160 | result.addNewlyCreatedParentNode(sequence); |
---|
161 | |
---|
162 | for (TaskTreeNode node : variant) |
---|
163 | { |
---|
164 | treeBuilder.addChild(sequence, node); |
---|
165 | } |
---|
166 | |
---|
167 | treeBuilder.addChild(selection, sequence); |
---|
168 | } |
---|
169 | } |
---|
170 | |
---|
171 | treeBuilder.setChild(newIteration, selection); |
---|
172 | } |
---|
173 | |
---|
174 | // remove iterated children |
---|
175 | for (int j = end; j >= start; j--) |
---|
176 | { |
---|
177 | treeBuilder.removeChild((Sequence) parent, j); |
---|
178 | } |
---|
179 | |
---|
180 | // add the new iteration instead |
---|
181 | treeBuilder.addChild((Sequence) parent, start, newIteration); |
---|
182 | |
---|
183 | result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED); |
---|
184 | return result; |
---|
185 | } |
---|
186 | } |
---|
187 | } |
---|
188 | |
---|
189 | return null; |
---|
190 | } |
---|
191 | |
---|
192 | //----------------------------------------------------------------------------------------------- |
---|
193 | /** |
---|
194 | * TODO: comment |
---|
195 | * |
---|
196 | * @return |
---|
197 | */ |
---|
198 | //----------------------------------------------------------------------------------------------- |
---|
199 | private List<TaskTreeNode[]> getEqualSublistVariantsInBoundaries(TaskTreeNode parent, |
---|
200 | int start, |
---|
201 | int end) |
---|
202 | { |
---|
203 | List<TaskTreeNode[]> equalVariants = null; |
---|
204 | |
---|
205 | int noOfChildrenInBoundaries = end - start + 1; |
---|
206 | |
---|
207 | for (int subListLength = 1; subListLength <= (noOfChildrenInBoundaries / 2); subListLength++) |
---|
208 | { |
---|
209 | if ((noOfChildrenInBoundaries % subListLength) == 0) |
---|
210 | { |
---|
211 | equalVariants = getEqualSublistVariantsForSubListLength(parent, start, end, subListLength); |
---|
212 | |
---|
213 | if (equalVariants != null) |
---|
214 | { |
---|
215 | return equalVariants; |
---|
216 | } |
---|
217 | } |
---|
218 | } |
---|
219 | |
---|
220 | return null; |
---|
221 | } |
---|
222 | |
---|
223 | //----------------------------------------------------------------------------------------------- |
---|
224 | /** |
---|
225 | * |
---|
226 | */ |
---|
227 | //----------------------------------------------------------------------------------------------- |
---|
228 | private List<TaskTreeNode[]> getEqualSublistVariantsForSubListLength(TaskTreeNode parent, |
---|
229 | int start, |
---|
230 | int end, |
---|
231 | int subListLength) |
---|
232 | { |
---|
233 | List<TaskTreeNode[]> equalVariants = new ArrayList<TaskTreeNode[]>(); |
---|
234 | TaskTreeNode[] firstVariant = new TaskTreeNode[subListLength]; |
---|
235 | |
---|
236 | for (int i = 0; i < subListLength; i++) |
---|
237 | { |
---|
238 | firstVariant[i] = parent.getChildren().get(start + i); |
---|
239 | } |
---|
240 | |
---|
241 | equalVariants.add(firstVariant); |
---|
242 | |
---|
243 | for (int parentIdx = (start + subListLength); parentIdx <= end; parentIdx += subListLength) |
---|
244 | { |
---|
245 | TaskTreeNode[] otherVariant = new TaskTreeNode[subListLength]; |
---|
246 | |
---|
247 | for (int i = 0; i < subListLength; i++) |
---|
248 | { |
---|
249 | NodeEquality nodeEquality = mNodeEqualityRuleManager.applyRules |
---|
250 | (firstVariant[i], parent.getChildren().get(parentIdx + i)); |
---|
251 | |
---|
252 | if (!nodeEquality.getStructuralEquality()) |
---|
253 | { |
---|
254 | if (nodeEquality.getSemanticalEquality()) |
---|
255 | { |
---|
256 | otherVariant[i] = parent.getChildren().get(parentIdx + i); |
---|
257 | } |
---|
258 | else |
---|
259 | { |
---|
260 | return null; |
---|
261 | } |
---|
262 | } |
---|
263 | } |
---|
264 | |
---|
265 | // check, if there is a semantically equal other variant. If so, add it to the list of |
---|
266 | // variants |
---|
267 | boolean semanticallyUnequal = false; |
---|
268 | for (int i = 0; i < subListLength; i++) |
---|
269 | { |
---|
270 | if (otherVariant[i] == null) |
---|
271 | { |
---|
272 | otherVariant[i] = firstVariant[i]; |
---|
273 | } |
---|
274 | else |
---|
275 | { |
---|
276 | semanticallyUnequal = true; |
---|
277 | } |
---|
278 | } |
---|
279 | |
---|
280 | if (semanticallyUnequal) |
---|
281 | { |
---|
282 | equalVariants.add(otherVariant); |
---|
283 | } |
---|
284 | } |
---|
285 | |
---|
286 | return equalVariants; |
---|
287 | } |
---|
288 | |
---|
289 | } |
---|