Changeset 1127
- Timestamp:
- 03/18/13 11:54:15 (12 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 9 edited
- 9 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/AbstractTemporalRelationshipTC.java
r1106 r1127 184 184 } 185 185 else { 186 status = RuleApplicationStatus. RULE_NOT_APPLIED;187 } 188 189 assertTrue(status != RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);186 status = RuleApplicationStatus.NOT_APPLIED; 187 } 188 189 assertTrue(status != RuleApplicationStatus.FEASIBLE); 190 190 191 191 if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) { … … 195 195 } 196 196 197 if (status == RuleApplicationStatus. RULE_NOT_APPLIED) {197 if (status == RuleApplicationStatus.NOT_APPLIED) { 198 198 toBeAppliedOn.pop(); 199 199 } 200 200 201 201 } 202 while ((!toBeAppliedOn.isEmpty()) || 203 (status == RuleApplicationStatus.RULE_APPLICATION_FINISHED)); 202 while ((!toBeAppliedOn.isEmpty()) || (status == RuleApplicationStatus.FINISHED)); 204 203 205 204 return taskTreeNodeFactory.createTaskTree(sequence); -
trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRuleTest.java
r1106 r1127 29 29 * @author 2012, last modified by $Author: patrick$ 30 30 */ 31 public class DefaultIterationDetectionRuleTest extends AbstractTemporalRelationshipTC {31 public class IterationOfSubtreesDetectionRuleTest extends AbstractTemporalRelationshipTC { 32 32 33 33 /** … … 42 42 ("Sequence sequence1 {" + 43 43 " Event bla {}" + 44 "}", getTaskTree( DefaultIterationDetectionRule.class, null));45 46 simulateEvent(event1, element1); 47 new TaskTreeChecker().assertTaskTree 48 ("Sequence sequence1 {" + 49 " Iteration iteration1 {" + 50 " Event bla {}" + 51 " }" + 52 "}", getTaskTree( DefaultIterationDetectionRule.class, null));53 54 simulateEvent(event1, element1); 55 new TaskTreeChecker().assertTaskTree 56 ("Sequence sequence1 {" + 57 " Iteration iteration1 {" + 58 " Event bla {}" + 59 " }" + 60 "}", getTaskTree( DefaultIterationDetectionRule.class, null));44 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 45 46 simulateEvent(event1, element1); 47 new TaskTreeChecker().assertTaskTree 48 ("Sequence sequence1 {" + 49 " Iteration iteration1 {" + 50 " Event bla {}" + 51 " }" + 52 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 53 54 simulateEvent(event1, element1); 55 new TaskTreeChecker().assertTaskTree 56 ("Sequence sequence1 {" + 57 " Iteration iteration1 {" + 58 " Event bla {}" + 59 " }" + 60 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 61 61 62 62 for (int i = 0; i < 10; i++) { … … 69 69 " Event bla {}" + 70 70 " }" + 71 "}", getTaskTree( DefaultIterationDetectionRule.class, null));71 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 72 72 73 73 // now test with preceding and trailing other events … … 95 95 " Event blup {}" + 96 96 " Event bli {}" + 97 "}", getTaskTree( DefaultIterationDetectionRule.class, null));97 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 98 98 99 99 // now test with iterations of iterations … … 136 136 " }" + 137 137 " }" + 138 "}", getTaskTree( DefaultIterationDetectionRule.class, null));138 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 139 139 140 140 } … … 157 157 " Event bli {}" + 158 158 " Event blup {}" + 159 "}", getTaskTree( DefaultIterationDetectionRule.class, null));160 161 simulateEvent(event1, element1); 162 simulateEvent(event2, element1); 163 simulateEvent(event3, element1); 164 new TaskTreeChecker().assertTaskTree 165 ("Sequence sequence1 {" + 166 " Iteration iteration1 {" + 167 " Sequence sequence2 {" + 168 " Event bla {}" + 169 " Event bli {}" + 170 " Event blup {}" + 171 " }" + 172 " }" + 173 "}", getTaskTree( DefaultIterationDetectionRule.class, null));174 175 simulateEvent(event1, element1); 176 simulateEvent(event2, element1); 177 simulateEvent(event3, element1); 178 new TaskTreeChecker().assertTaskTree 179 ("Sequence sequence1 {" + 180 " Iteration iteration1 {" + 181 " Sequence sequence2 {" + 182 " Event bla {}" + 183 " Event bli {}" + 184 " Event blup {}" + 185 " }" + 186 " }" + 187 "}", getTaskTree( DefaultIterationDetectionRule.class, null));159 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 160 161 simulateEvent(event1, element1); 162 simulateEvent(event2, element1); 163 simulateEvent(event3, element1); 164 new TaskTreeChecker().assertTaskTree 165 ("Sequence sequence1 {" + 166 " Iteration iteration1 {" + 167 " Sequence sequence2 {" + 168 " Event bla {}" + 169 " Event bli {}" + 170 " Event blup {}" + 171 " }" + 172 " }" + 173 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 174 175 simulateEvent(event1, element1); 176 simulateEvent(event2, element1); 177 simulateEvent(event3, element1); 178 new TaskTreeChecker().assertTaskTree 179 ("Sequence sequence1 {" + 180 " Iteration iteration1 {" + 181 " Sequence sequence2 {" + 182 " Event bla {}" + 183 " Event bli {}" + 184 " Event blup {}" + 185 " }" + 186 " }" + 187 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 188 188 189 189 for (int i = 0; i < 10; i++) { … … 202 202 " }" + 203 203 " }" + 204 "}", getTaskTree( DefaultIterationDetectionRule.class, null));204 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 205 205 206 206 // now test with preceding and trailing other events … … 242 242 " Event blo {}" + 243 243 " Event ble {}" + 244 "}", getTaskTree( DefaultIterationDetectionRule.class, null));244 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 245 245 246 246 // now test with iterations of iterations … … 310 310 " }" + 311 311 " }" + 312 "}", getTaskTree( DefaultIterationDetectionRule.class, null));312 "}", getTaskTree(IterationOfSubtreesDetectionRule.class, null)); 313 313 } 314 314 -
trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRuleTest.java
r1106 r1127 28 28 * @author 2011, last modified by $Author: $ 29 29 */ 30 public class DefaultGuiEventSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {30 public class SequenceDependingOnEventTypeDetectionRuleTest extends AbstractTemporalRelationshipTC { 31 31 32 32 /** … … 43 43 " Event start {}" + 44 44 " Event end {}" + 45 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));45 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 46 46 } 47 47 … … 62 62 " Event bla {}" + 63 63 " Event end {}" + 64 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));64 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 65 65 } 66 66 … … 96 96 " Event end {}" + 97 97 " }" + 98 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));98 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 99 99 } 100 100 … … 128 128 " }" + 129 129 " Event startFinish {}" + 130 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));130 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 131 131 } 132 132 … … 190 190 " }" + 191 191 " Event finish {}" + 192 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));192 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 193 193 } 194 194 … … 260 260 " }" + 261 261 " Event finish {}" + 262 "}", getTaskTree( DefaultGuiEventSequenceDetectionRule.class, null));262 "}", getTaskTree(SequenceDependingOnEventTypeDetectionRule.class, null)); 263 263 } 264 264 -
trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleTest.java
r1109 r1127 20 20 import de.ugoe.cs.autoquest.eventcore.gui.IInteraction; 21 21 import de.ugoe.cs.autoquest.tasktrees.TaskTreeChecker; 22 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 22 23 import de.ugoe.cs.autoquest.test.DummyGUIElement; 23 24 import de.ugoe.cs.autoquest.test.DummyInteraction; … … 29 30 * @author 2012, last modified by $Author: patrick$ 30 31 */ 31 public class DefaultTaskSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {32 public class SequenceForTaskDetectionRuleTest extends AbstractTemporalRelationshipTC { 32 33 33 34 /** … … 65 66 simulateEvent(new DummyInteraction("noise8", 1), element1); 66 67 67 new TaskTreeChecker().assertTaskTree 68 ("Sequence sequence1 {" + 69 " Event noise0 {}" + 70 " Sequence sequence2 {" + 71 " Event action1 {}" + 72 " Event action2 {}" + 73 " Event action3 {}" + 74 " Event action4 {}" + 68 new TaskTreeChecker(true).assertTaskTree 69 ("Sequence root {" + 70 " Sequence session1 {" + 71 " Event noise0 {}" + 72 " Sequence sequence2 {" + 73 " Event action1 {}" + 74 " Event action2 {}" + 75 " Event action3 {}" + 76 " Event action4 {}" + 77 " }" + 78 " Event noise1 {}" + 79 " Event noise2 {}" + 80 " Sequence sequence2 {" + 81 " Event action1 {}" + 82 " Event action2 {}" + 83 " Event action3 {}" + 84 " Event action4 {}" + 85 " }" + 86 " Event noise3 {}" + 87 " Event noise4 {}" + 88 " Event noise5 {}" + 89 " Event noise6 {}" + 90 " Sequence sequence2 {" + 91 " Event action1 {}" + 92 " Event action2 {}" + 93 " Event action3 {}" + 94 " Event action4 {}" + 95 " }" + 96 " Event noise7 {}" + 97 " Event noise8 {}" + 75 98 " }" + 76 " Event noise1 {}" + 77 " Event noise2 {}" + 78 " Sequence sequence2 {" + 79 " Event action1 {}" + 80 " Event action2 {}" + 81 " Event action3 {}" + 82 " Event action4 {}" + 83 " }" + 84 " Event noise3 {}" + 85 " Event noise4 {}" + 86 " Event noise5 {}" + 87 " Event noise6 {}" + 88 " Sequence sequence2 {" + 89 " Event action1 {}" + 90 " Event action2 {}" + 91 " Event action3 {}" + 92 " Event action4 {}" + 93 " }" + 94 " Event noise7 {}" + 95 " Event noise8 {}" + 96 "}", getTaskTree()); 99 "}", getTaskTree(SequenceForTaskDetectionRule.class, NodeEquality.LEXICALLY_EQUAL)); 97 100 98 101 } -
trunk/autoquest-core-tasktrees-test/src/test/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRuleTest.java
r1106 r1127 28 28 * @author 2011, last modified by $Author: $ 29 29 */ 30 public class DefaultGuiElementSequenceDetectionRuleTest extends AbstractTemporalRelationshipTC {30 public class SequenceOnGuiElementDetectionRuleTest extends AbstractTemporalRelationshipTC { 31 31 32 32 /** … … 62 62 " Event blu {}" + 63 63 " Event bla {}" + 64 "}", getTaskTree( DefaultGuiElementSequenceDetectionRule.class, null));64 "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null)); 65 65 } 66 66 … … 103 103 " Event bla {}" + 104 104 " }" + 105 "}", getTaskTree( DefaultGuiElementSequenceDetectionRule.class, null));105 "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null)); 106 106 } 107 107 … … 162 162 " Event blo {}" + 163 163 " }" + 164 "}", getTaskTree( DefaultGuiElementSequenceDetectionRule.class, null));164 "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null)); 165 165 } 166 166 … … 233 233 " }" + 234 234 " }" + 235 "}", getTaskTree( DefaultGuiElementSequenceDetectionRule.class, null));235 "}", getTaskTree(SequenceOnGuiElementDetectionRule.class, null)); 236 236 } 237 237 -
trunk/autoquest-core-tasktrees/pom.xml
r1108 r1127 28 28 <version>${project.parent.version}</version> 29 29 </dependency> 30 <dependency> 31 <groupId>com.googlecode.java-diff-utils</groupId> 32 <artifactId>diffutils</artifactId> 33 <version>1.2.1</version> 34 </dependency> 30 35 </dependencies> 31 36 </project> -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/IterationOfSubtreesDetectionRule.java
r1117 r1127 75 75 * @author Patrick Harms 76 76 */ 77 class DefaultIterationDetectionRule implements TemporalRelationshipRule {77 class IterationOfSubtreesDetectionRule implements TemporalRelationshipRule { 78 78 79 79 /** … … 101 101 /** 102 102 * <p> 103 * the node equality manager needed for comparing task tree nodes with each other 104 * </p> 105 */ 106 private NodeEqualityRuleManager nodeEqualityRuleManager; 107 108 /** 109 * <p> 110 * the minimal node equality two identified sublists need to have to consider them as equal 111 * and to create an iteration for 112 * </p> 113 */ 114 private NodeEquality minimalNodeEquality; 103 * the node comparator used for comparing task tree nodes with each other 104 * </p> 105 */ 106 private TaskTreeNodeComparator nodeComparator; 115 107 116 108 /** … … 120 112 * </p> 121 113 */ 122 DefaultIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,123 NodeEquality minimalNodeEquality,124 ITaskTreeNodeFactory taskTreeNodeFactory,125 ITaskTreeBuilder taskTreeBuilder)114 IterationOfSubtreesDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager, 115 NodeEquality minimalNodeEquality, 116 ITaskTreeNodeFactory taskTreeNodeFactory, 117 ITaskTreeBuilder taskTreeBuilder) 126 118 { 127 this.nodeEqualityRuleManager = nodeEqualityRuleManager;128 this.minimalNodeEquality = minimalNodeEquality;129 119 this.taskTreeNodeFactory = taskTreeNodeFactory; 130 120 this.taskTreeBuilder = taskTreeBuilder; 121 122 this.nodeComparator = 123 new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality); 124 } 125 126 /** 127 * <p> 128 * instantiates the rule and initializes it with a node equality rule manager and the minimal 129 * node equality identified sublist must have to consider them as iterated. 130 * </p> 131 */ 132 IterationOfSubtreesDetectionRule(TaskTreeNodeComparator nodeComparator, 133 ITaskTreeNodeFactory taskTreeNodeFactory, 134 ITaskTreeBuilder taskTreeBuilder) 135 { 136 this.nodeComparator = nodeComparator; 137 this.taskTreeNodeFactory = taskTreeNodeFactory; 138 this.taskTreeBuilder = taskTreeBuilder; 131 139 } 132 140 … … 136 144 @Override 137 145 public String toString() { 138 return " DefaultIterationDetectionRule";146 return "IterationOfSubtreesDetectionRule"; 139 147 } 140 148 … … 154 162 // the rule is always feasible as iterations may occur at any time 155 163 RuleApplicationResult result = new RuleApplicationResult(); 156 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);164 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 157 165 return result; 158 166 } 159 167 168 List<ITaskTreeNode> children = parent.getChildren(); 169 160 170 // parent must already have at least 2 children 161 if (( parent.getChildren() == null) || (parent.getChildren().size() < 2)) {171 if ((children == null) || (children.size() < 2)) { 162 172 return null; 163 173 } 164 174 165 166 SubSequences subSequences = getEqualSubsequences(parent); 175 SubSequences subSequences = getEqualSubsequences(children); 167 176 168 177 if (subSequences != null) { 169 178 RuleApplicationResult result = new RuleApplicationResult(); 170 179 171 mergeEqualNodes(subSequences.equalVariants); 180 // merge the identified variants, but preserve the differences in form of selections 181 // by using lexical equality for merge comparisons 182 TaskTreeNodeMerger merger = new TaskTreeNodeMerger 183 (taskTreeNodeFactory, taskTreeBuilder, nodeComparator); 184 185 merger.mergeTaskNodes(subSequences.equalVariants); 186 172 187 IIteration newIteration = 173 188 createIterationBasedOnIdentifiedVariants(subSequences, result); … … 183 198 taskTreeBuilder.addChild((ISequence) parent, subSequences.start, newIteration); 184 199 185 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FINISHED);200 result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 186 201 return result; 187 202 } … … 193 208 * <p> 194 209 * this method initiates the trial and error algorithm denoted in the description of this class. 195 * Its main purpose is the selection of a subpart of all children in the parent nodein which210 * Its main purpose is the selection of a subpart of the provided list of nodes in which 196 211 * equal sublists shall be searched. It is important, to always find the last iterations in a 197 212 * part first. The reason for this are iterations of iterations. If we always found the first … … 202 217 * </p> 203 218 * 204 * @param parent the parent node in which iterations of childrenshall be found219 * @param nodes the list of nodes in which iterations shall be found 205 220 * 206 221 * @return the iterated subsequences identified in a specific part (contains the equal … … 208 223 * subpart in which the sequences were found) 209 224 */ 210 private SubSequences getEqualSubsequences( ITaskTreeNode parent) {225 private SubSequences getEqualSubsequences(List<ITaskTreeNode> nodes) { 211 226 SubSequences subSequences = null; 212 227 213 228 // to find longer iterations first, start with long sequences 214 229 FIND_ITERATION: 215 for (int end = parent.getChildren().size(); end > 0; end--) {230 for (int end = nodes.size(); end > 0; end--) { 216 231 for (int start = 0; start < end; start++) { 217 boolean useEqualSublistLengths = equalSublistLengthsCanBeUsed( parent, start, end);232 boolean useEqualSublistLengths = equalSublistLengthsCanBeUsed(nodes, start, end); 218 233 219 234 subSequences = new SubSequences(); … … 221 236 222 237 boolean foundFurtherVariants = findFurtherVariants 223 (subSequences, parent, start, end, useEqualSublistLengths);238 (subSequences, nodes, start, end, useEqualSublistLengths); 224 239 225 240 if (foundFurtherVariants) { … … 239 254 * for optimization purposes, we check if the length of the sublists to be identified as 240 255 * iterations has to be the same for any sublist. This only applies, if the minimum node 241 * equality to be checked for is lexical equality. If the children of the parent are all event242 * tasks, then sublists can only be lexically equal, if they all have the same length.256 * equality to be checked for is lexical equality. If the nodes in the provided list are all 257 * event tasks, then sublists can only be lexically equal, if they all have the same length. 243 258 * Therefore we check, if the minimal node equality is lexical equality. And if so, we also 244 * check if all children of the parent in which an iteration shall be searched for are event 245 * tasks. 259 * check if all nodes in the list in which an iteration shall be searched for are event tasks. 246 260 * </p> 247 261 * 248 * @param parent the parent node to search for iterations of its children262 * @param nodes the list of nodes to search for iterations 249 263 * @param start the beginning of the subpart (inclusive) to be considered 250 264 * @param end the end of the subpart (exclusive) to be considered … … 252 266 * @return true, if the sublists must have the same lengths, false else 253 267 */ 254 private boolean equalSublistLengthsCanBeUsed(ITaskTreeNode parent, int start, int end) { 255 boolean equalLengthsCanBeUsed = minimalNodeEquality.isAtLeast(NodeEquality.LEXICALLY_EQUAL); 268 private boolean equalSublistLengthsCanBeUsed(List<ITaskTreeNode> nodes, int start, int end) { 269 boolean equalLengthsCanBeUsed = 270 nodeComparator.getConsideredNodeEquality().isAtLeast(NodeEquality.LEXICALLY_EQUAL); 256 271 257 272 if (equalLengthsCanBeUsed) { 258 273 for (int i = start; i < end; i++) { 259 if (!( parent.getChildren().get(i) instanceof IEventTask)) {274 if (!(nodes.get(i) instanceof IEventTask)) { 260 275 equalLengthsCanBeUsed = false; 261 276 break; … … 269 284 /** 270 285 * <p> 271 * this method starts at a specific position in the list of children of the provided parent272 * and checks, if it finds a further sublist, that matches the already found sublists. If273 * the sublist lengths must be equal, it only searches for a sublist of the same length of the274 * already foundsublists. The method calls itself if it identifies a further equal sublist but275 * if the end of the subpart of childrenis not yet reached.286 * this method starts at a specific position in the provided list of nodes and checks, if it 287 * finds a further sublist, that matches the already found sublists. If the sublist lengths 288 * must be equal, it only searches for a sublist of the same length of the already found 289 * sublists. The method calls itself if it identifies a further equal sublist but 290 * if the end of the subpart of the provided list is not yet reached. 276 291 * </p> 277 292 * 278 293 * @param subSequences the sublist found so far against which equality of the next 279 294 * sublist must be checked 280 * @param parent the parent node of which the children are analyzed295 * @param nodes the list of nodes to be checked for iterations 281 296 * @param start the starting index from which to start the next sublist to be 282 297 * identified 283 * @param end the end index (exclusive) of the current subpart of children284 * in which iterations are searched for298 * @param end the end index (exclusive) of the current subpart of list of 299 * nodes in which iterations are searched for 285 300 * @param useEqualSublistLengths true if the sublists to be searched for all need to have the 286 301 * same length … … 288 303 * @return true if a further equal variant was found, false else 289 304 */ 290 private boolean findFurtherVariants(SubSequences 291 ITaskTreeNode parent,292 int 293 int 294 boolean 305 private boolean findFurtherVariants(SubSequences subSequences, 306 List<ITaskTreeNode> nodes, 307 int start, 308 int end, 309 boolean useEqualSublistLengths) 295 310 { 296 311 boolean foundFurtherVariants = (start == end) && (subSequences.equalVariants.size() > 1); … … 312 327 313 328 for (int j = start; j < start + childCount; j++) { 314 taskTreeBuilder.addChild(furtherVariant, parent.getChildren().get(j));329 taskTreeBuilder.addChild(furtherVariant, nodes.get(j)); 315 330 } 316 331 … … 318 333 319 334 for (ITaskTreeNode equalVariant : subSequences.equalVariants) { 320 NodeEquality nodeEquality = 321 nodeEqualityRuleManager.applyRules(equalVariant, furtherVariant); 322 323 if (!nodeEquality.isAtLeast(minimalNodeEquality)) { 335 if (!nodeComparator.equals(equalVariant, furtherVariant)) { 324 336 allVariantsEqual = false; 325 337 break; … … 335 347 336 348 foundFurtherVariants = findFurtherVariants 337 (subSequences, parent, start + childCount, end, useEqualSublistLengths);349 (subSequences, nodes, start + childCount, end, useEqualSublistLengths); 338 350 339 351 if (foundFurtherVariants) { … … 348 360 349 361 return foundFurtherVariants; 350 }351 352 /**353 * <p>354 * this method merges task tree nodes in a list, if they can be merged. for this, it tries355 * to merge every node with every other node in the provided list using the356 * {@link #mergeEqualTasks(ITaskTreeNode, ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory)}357 * method. If a merge is possible, it removes the merged nodes from the list and adds the358 * merge result.359 * </p>360 *361 * @param nodes the list of nodes to be merged362 */363 private void mergeEqualNodes(List<ITaskTreeNode> nodes) {364 int index1 = 0;365 int index2 = 0;366 ITaskTreeNode variant1;367 ITaskTreeNode variant2;368 369 while (index1 < nodes.size()) {370 variant1 = nodes.get(index1);371 index2 = index1 + 1;372 373 while (index2 < nodes.size()) {374 variant2 = nodes.get(index2);375 ITaskTreeNode mergedChild = mergeEqualTasks(variant1, variant2);376 377 if (mergedChild != null) {378 // if we merged something start from the beginning to perform the next merge379 nodes.remove(index2);380 nodes.remove(index1);381 nodes.add(index1, mergedChild);382 index1 = -1;383 break;384 }385 else {386 index2++;387 }388 }389 390 index1++;391 }392 }393 394 /**395 * <p>396 * this method merges two equal tasks with each other if possible. If the tasks are lexically397 * equal, the first of them is returned as merge result. If both tasks are of the same398 * temporal relationship type, the appropriate merge method is called to merge them. If one399 * of the nodes is a selection, the other one is added as a variant of this selection.400 * (However, if both nodes are selections, they are merged using the appropriate merge method.)401 * If merging is not possible, then a selection of both provided nodes is created and402 * returned as merge result.403 * </p>404 *405 * @param node1 the first task to be merged406 * @param node2 the second task to be merged407 *408 * @return the result of the merge409 */410 private ITaskTreeNode mergeEqualTasks(ITaskTreeNode node1, ITaskTreeNode node2) {411 ITaskTreeNode mergeResult = null;412 413 if ((node1 instanceof ISequence) && (node2 instanceof ISequence)) {414 mergeResult = mergeEqualSequences((ISequence) node1, (ISequence) node2);415 }416 else if ((node1 instanceof ISelection) && (node2 instanceof ISelection)) {417 mergeResult = mergeEqualSelections((ISelection) node1, (ISelection) node2);418 }419 else if ((node1 instanceof IIteration) && (node2 instanceof IIteration)) {420 mergeResult = mergeEqualIterations((IIteration) node1, (IIteration) node2);421 }422 else if (node1 instanceof ISelection) {423 taskTreeBuilder.addChild((ISelection) node1, node2);424 mergeResult = node1;425 }426 else if (node2 instanceof ISelection) {427 taskTreeBuilder.addChild((ISelection) node2, node1);428 mergeResult = node2;429 }430 else if (node1 instanceof IIteration) {431 mergeResult = mergeEqualTasks(((IIteration) node1).getChildren().get(0), node2);432 433 if (mergeResult != null) {434 IIteration iteration = taskTreeNodeFactory.createNewIteration();435 taskTreeBuilder.setChild(iteration, mergeResult);436 mergeResult = iteration;437 }438 }439 else if (node2 instanceof IIteration) {440 mergeResult = mergeEqualTasks(((IIteration) node2).getChildren().get(0), node1);441 442 if (mergeResult != null) {443 IIteration iteration = taskTreeNodeFactory.createNewIteration();444 taskTreeBuilder.setChild(iteration, mergeResult);445 mergeResult = iteration;446 }447 }448 else {449 NodeEquality nodeEquality = nodeEqualityRuleManager.applyRules(node1, node2);450 451 if (nodeEquality.isAtLeast(NodeEquality.LEXICALLY_EQUAL)) {452 mergeResult = node1;453 }454 }455 456 if (mergeResult == null) {457 mergeResult = taskTreeNodeFactory.createNewSelection();458 taskTreeBuilder.addChild((ISelection) mergeResult, node1);459 taskTreeBuilder.addChild((ISelection) mergeResult, node2);460 }461 462 return mergeResult;463 }464 465 /**466 * <p>467 * merges equal sequences. This is done through trying to merge each node of sequence 1 with468 * the node in sequence 2 being located at the same position. If not all children can be merged469 * or if the sequences have different lengths, null is returned to indicate, that merging is470 * not possible. For merging children, the471 * {@link #mergeEqualTasks(ITaskTreeNode, ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory)}472 * method is called.473 * </p>474 *475 * @param sequence1 the first sequence to be merged476 * @param sequence2 the second sequence to be merged477 *478 * @return the result of the merge or null if merging was not possible479 */480 private ISequence mergeEqualSequences(ISequence sequence1, ISequence sequence2) {481 ISequence mergeResult = null;482 483 if (sequence1.getChildren().size() == sequence2.getChildren().size()) {484 mergeResult = taskTreeNodeFactory.createNewSequence();485 486 for (int i = 0; i < sequence1.getChildren().size(); i++) {487 ITaskTreeNode mergedNode = mergeEqualTasks488 (sequence1.getChildren().get(i), sequence2.getChildren().get(i));489 490 if (mergedNode != null) {491 taskTreeBuilder.addChild(mergeResult, mergedNode);492 }493 else {494 mergeResult = null;495 break;496 }497 }498 }499 500 return mergeResult;501 }502 503 /**504 * <p>505 * merges equal selections. This is done by adding those children of the second selection to506 * the first selection that can not be merged with any of the children of the first selection.507 * If a merge is possible and this merge is not a simple selection of the merged children,508 * then the merged child replaces the child of the first selection which was merged.509 * </p>510 *511 * @param selection1 the first selection to be merged512 * @param selection2 the second selection to be merged513 *514 * @return the result of the merge which is never null515 */516 private ITaskTreeNode mergeEqualSelections(ISelection selection1, ISelection selection2) {517 ISelection mergeResult = selection1;518 519 ITaskTreeNode childToMerge = null;520 ITaskTreeNode mergedChild = null;521 522 // check for each child of selection 2 if it is a duplicate of one of the children523 // if selection 1. If not, add it as further child to the merge result, else skip it.524 for (int i = 0; i < selection2.getChildren().size(); i++) {525 childToMerge = selection2.getChildren().get(i);526 for (int j = 0; j < selection1.getChildren().size(); j++) {527 mergedChild = mergeEqualTasks(selection1.getChildren().get(j), childToMerge);528 529 // a merge must not be a selection, except it is one of the children. Otherwise530 // no real merge was done.531 if ((mergedChild != null) &&532 ((!(mergedChild instanceof ISelection)) ||533 (selection1.getChildren().get(j) == mergedChild) ||534 (childToMerge == mergedChild)))535 {536 // we found a real merge. So replace the original child in selection 1 with537 // the merged child538 taskTreeBuilder.removeChild(selection1, selection1.getChildren().get(j));539 taskTreeBuilder.addChild(selection1, mergedChild);540 mergedChild = null;541 childToMerge = null;542 break;543 }544 }545 546 if (childToMerge != null) {547 taskTreeBuilder.addChild(selection1, childToMerge);548 }549 }550 551 return mergeResult;552 }553 554 /**555 * <p>556 * merges equal iterations. This is done through merging the children of both iterations. If557 * this is possible, a resulting iteration with the merge result of the children as its own558 * child is returned. Otherwise null is returned to indicate that merging was not possible.559 * </p>560 *561 * @param selection1 the first iteration to be merged562 * @param selection2 the second iteration to be merged563 *564 * @return the result of the merge or null if merging is not possible565 */566 private ITaskTreeNode mergeEqualIterations(IIteration iteration1, IIteration iteration2) {567 ITaskTreeNode mergedChild = mergeEqualTasks568 (iteration1.getChildren().get(0), iteration2.getChildren().get(0));569 570 IIteration mergeResult = null;571 572 if (mergedChild != null) {573 mergeResult = taskTreeNodeFactory.createNewIteration();574 taskTreeBuilder.setChild(mergeResult, mergedChild);575 }576 577 return mergeResult;578 362 } 579 363 … … 691 475 List<ITaskTreeNode> parentNodes = new ArrayList<ITaskTreeNode>(); 692 476 693 if (subtree.getChildren().size() > 0) { 477 List<ITaskTreeNode> children = subtree.getChildren(); 478 479 if (children.size() > 0) { 694 480 parentNodes.add(subtree); 695 481 696 for (ITaskTreeNode child : subtree.getChildren()) {482 for (ITaskTreeNode child : children) { 697 483 parentNodes.addAll(getParentNodes(child)); 698 484 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java
r1113 r1127 33 33 34 34 /** */ 35 private RuleApplicationStatus status = RuleApplicationStatus. RULE_NOT_APPLIED;35 private RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED; 36 36 37 37 /** */ -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java
r1113 r1127 24 24 */ 25 25 enum RuleApplicationStatus { 26 RULE_APPLICATION_FINISHED,27 RULE_APPLICATION_FEASIBLE,28 RULE_NOT_APPLIED;26 FINISHED, 27 FEASIBLE, 28 NOT_APPLIED; 29 29 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java
r1107 r1127 35 35 * 36 36 */ 37 static ISequence getSubSequenceInRange(ITaskTreeNode parent, 38 int startIndex, 39 int endIndex, 40 String description, 41 ITaskTreeNodeFactory nodeFactory, 42 ITaskTreeBuilder builder) 43 { 44 ISequence sequence = nodeFactory.createNewSequence(); 45 if (description != null) { 46 builder.setDescription(sequence, description); 47 } 48 49 for (int i = startIndex; i <= endIndex; i++) { 50 builder.addChild(sequence, parent.getChildren().get(i)); 51 } 52 53 return sequence; 54 } 55 56 /** 57 * 58 */ 37 59 static ISequence createNewSubSequenceInRange(ITaskTreeNode parent, 38 60 int startIndex, … … 60 82 * 61 83 */ 62 publicstatic synchronized String getNewId() {84 static synchronized String getNewId() { 63 85 return Integer.toString(idCounter++); 64 86 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceDependingOnEventTypeDetectionRule.java
r1117 r1127 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 16 17 import java.util.List; 17 18 import java.util.Stack; 18 19 … … 34 35 * @author 2012, last modified by $Author: patrick$ 35 36 */ 36 class DefaultGuiEventSequenceDetectionRule implements TemporalRelationshipRule {37 class SequenceDependingOnEventTypeDetectionRule implements TemporalRelationshipRule { 37 38 38 39 /** … … 63 64 * the temporal relationships identified during rule application 64 65 */ 65 DefaultGuiEventSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,66 ITaskTreeBuilder taskTreeBuilder)66 SequenceDependingOnEventTypeDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory, 67 ITaskTreeBuilder taskTreeBuilder) 67 68 { 68 69 this.taskTreeNodeFactory = taskTreeNodeFactory; … … 75 76 @Override 76 77 public String toString() { 77 return " DefaultGuiEventSequenceDetectionRule";78 return "SequenceDependingOnEventTypeDetectionRule"; 78 79 } 79 80 … … 93 94 Stack<Integer> sequenceStartingIndex = new Stack<Integer>(); 94 95 96 List<ITaskTreeNode> children = parent.getChildren(); 97 95 98 int index = 0; 96 while (index < parent.getChildren().size()) {97 ITaskTreeNode child = parent.getChildren().get(index);99 while (index < children.size()) { 100 ITaskTreeNode child = children.get(index); 98 101 99 102 if ((child instanceof IEventTask) && … … 104 107 if (eventType.finishesLogicalSequence() && (sequenceStartingIndex.size() > 0)) { 105 108 index = handleLogicalSequence(sequenceStartingIndex, index, parent, result); 109 // the parents child list will have changed, retrieve it again 110 children = parent.getChildren(); 106 111 } 107 112 … … 116 121 if (sequenceStartingIndex.size() > 0) { 117 122 if (!finalize) { 118 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);123 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 119 124 } 120 125 else { 121 ITaskTreeNode lastChild = parent.getChildren().get(parent.getChildren().size() - 1);126 ITaskTreeNode lastChild = children.get(children.size() - 1); 122 127 123 128 if (lastChild instanceof IEventTask) { 124 129 handleLogicalSequence 125 (sequenceStartingIndex, parent.getChildren().size() - 1, parent, result);130 (sequenceStartingIndex, children.size() - 1, parent, result); 126 131 } 127 132 } … … 143 148 { 144 149 int newIndex = index; 150 151 List<ITaskTreeNode> children = parent.getChildren(); 152 145 153 IInteraction eventType = 146 (IInteraction) ((IEventTask) parent.getChildren().get(index)).getEventType();154 (IInteraction) ((IEventTask) children.get(index)).getEventType(); 147 155 148 156 // There are several situations in which this implementation may cause infinite … … 163 171 164 172 boolean allChildrenBelongToSubSequence = 165 (sequenceStartingIndex.peek() == 0) && (index == ( parent.getChildren().size() - 1));173 (sequenceStartingIndex.peek() == 0) && (index == (children.size() - 1)); 166 174 167 175 boolean atLeastOneChildToCondense = index - sequenceStartingIndex.peek() > 0; … … 172 180 173 181 for (int j = startIndex; j < index; j++) { 174 taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex));182 taskTreeBuilder.addChild(sequence, children.get(startIndex)); 175 183 taskTreeBuilder.removeChild((ISequence) parent, startIndex); 176 184 } 177 185 178 186 if (!eventType.startsLogicalSequence()) { 179 taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex));187 taskTreeBuilder.addChild(sequence, children.get(startIndex)); 180 188 taskTreeBuilder.removeChild((ISequence) parent, startIndex); 181 189 newIndex = startIndex; … … 191 199 taskTreeBuilder.setDescription(sequence, "logical sequence started by the first event"); 192 200 193 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FINISHED);201 result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 194 202 } 195 203 -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java
r1119 r1127 21 21 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 22 22 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; 23 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 24 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 23 25 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 24 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder; 25 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 26 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory; 27 import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;28 29 import de.ugoe.cs.autoquest.usageprofiles.Trie; 29 30 import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor; 31 import de.ugoe.cs.util.console.Console; 30 32 31 33 /** … … 36 38 * @author Patrick Harms 37 39 */ 38 class DefaultTaskSequenceDetectionRule implements TemporalRelationshipRule {40 class SequenceForTaskDetectionRule implements TemporalRelationshipRule { 39 41 40 42 /** … … 58 60 * </p> 59 61 */ 60 private SymbolComparator<ITaskTreeNode>nodeComparator;62 private TaskTreeNodeComparator nodeComparator; 61 63 62 64 /** … … 66 68 * </p> 67 69 */ 68 DefaultTaskSequenceDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,69 70 71 70 SequenceForTaskDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager, 71 NodeEquality minimalNodeEquality, 72 ITaskTreeNodeFactory taskTreeNodeFactory, 73 ITaskTreeBuilder taskTreeBuilder) 72 74 { 73 75 this.taskTreeNodeFactory = taskTreeNodeFactory; … … 83 85 @Override 84 86 public String toString() { 85 return " DefaultTaskSequenceDetectionRule";87 return "SequenceForTaskDetectionRule"; 86 88 } 87 89 … … 101 103 // the rule is always feasible as tasks may occur at any time 102 104 RuleApplicationResult result = new RuleApplicationResult(); 103 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);105 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 104 106 return result; 105 107 } 106 108 107 RuleApplicationData<ITaskTreeNode> appData = new RuleApplicationData<ITaskTreeNode>(parent); 108 109 appData.getStopWatch().start("whole rule application"); 110 109 List<ITaskTreeNode> children = parent.getChildren(); 110 List<ISequence> sessions = new LinkedList<ISequence>(); 111 112 for (ITaskTreeNode child : children) { 113 if (child instanceof ISequence) { 114 sessions.add((ISequence) child); 115 } 116 else { 117 Console.println("provided parent is no parent of sessions"); 118 return null; 119 } 120 } 121 122 RuleApplicationData appData = new RuleApplicationData(sessions); 123 124 boolean finished = false; 125 126 // this is the real rule application. Loop while something is replaced. 111 127 do { 112 getSequencesOccuringMostOften(appData); 113 114 if ((appData.getLastFoundSequences().size() > 0) && 115 (appData.getLastFoundSequences().getOccurrenceCount() > 1)) 116 { 117 System.out.println("found " + appData.getLastFoundSequences().size() + 118 " tasks occurring " + 119 appData.getLastFoundSequences().getOccurrenceCount() + " times"); 120 121 for (List<ITaskTreeNode> task : appData.getLastFoundSequences()) { 122 // only tasks occurring more often than once are of interest 123 appData.stopWatch.start("creating task sequences"); 124 125 String taskId = "task " + RuleUtils.getNewId(); 126 System.out.println(taskId + ": " + task); 127 128 appData.resetReplacementCounter(); 129 createSequenceForTaskOccurrences(taskId, task, parent, appData); 130 131 if (appData.getReplacementCounter() < 132 appData.getLastFoundSequences().getOccurrenceCount()) 133 { 134 System.out.println(taskId + ": replaced task only " + 135 appData.getReplacementCounter() + 136 " times instead of expected " + 137 appData.getLastFoundSequences().getOccurrenceCount()); 138 139 } 140 141 appData.stopWatch.stop("creating task sequences"); 128 System.out.println(); 129 130 appData.getStopWatch().start("whole loop"); 131 detectAndReplaceIterations(appData); 132 //mergeEqualTasks(appData); 133 appData.getStopWatch().start("task replacement"); 134 detectAndReplaceTasks(appData); 135 appData.getStopWatch().stop("task replacement"); 136 appData.getStopWatch().stop("whole loop"); 137 138 //((TaskTreeNodeComparator) nodeComparator).getStopWatch().dumpStatistics(System.out); 139 //((TaskTreeNodeComparator) nodeComparator).getStopWatch().reset(); 140 141 appData.getStopWatch().dumpStatistics(System.out); 142 appData.getStopWatch().reset(); 143 144 finished = (appData.getReplacementCounter() == 0); 145 } 146 while (!finished); 147 148 System.out.println("created " + appData.getResult().getNewlyCreatedParentNodes().size() + 149 " new parent nodes\n"); 150 151 if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) { 152 appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 153 } 154 155 return appData.getResult(); 156 } 157 158 /** 159 * <p> 160 * TODO: comment 161 * </p> 162 * 163 * @param appData 164 */ 165 private void detectAndReplaceIterations(RuleApplicationData appData) { 166 System.out.print("detecting iterations"); 167 appData.getStopWatch().start("detecting iterations"); 168 169 List<ISequence> sessions = appData.getSessions(); 170 int foundIterations = 0; 171 172 for (ISequence session : sessions) { 173 foundIterations += detectAndReplaceIterations(session, appData); 174 } 175 176 appData.getStopWatch().stop("detecting iterations"); 177 System.out.println(" --> found " + foundIterations); 178 } 179 180 /** 181 * <p> 182 * TODO: comment 183 * </p> 184 * 185 * @param appData 186 */ 187 private int detectAndReplaceIterations(ISequence session, 188 RuleApplicationData appData) 189 { 190 int count = 0; 191 192 TemporalRelationshipRule rule = new SimpleIterationDetectionRule 193 (nodeComparator, taskTreeNodeFactory, taskTreeBuilder); 194 195 RuleApplicationResult result = rule.apply(session, true); 196 197 if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) { 198 for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { 199 appData.getResult().addNewlyCreatedParentNode(newParent); 200 if (newParent instanceof IIteration) { 201 count++; 142 202 } 143 203 } 144 145 } 146 while (appData.getLastFoundSequences().getOccurrenceCount() > 2); 147 148 appData.getStopWatch().stop("whole rule application"); 149 appData.getStopWatch().dumpStatistics(System.out); 150 151 if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) { 152 appData.getResult().setRuleApplicationStatus 153 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); 154 } 155 156 System.out.println(appData.getResult().getNewlyCreatedParentNodes().size()); 157 158 for (ITaskTreeNode node : appData.getResult().getNewlyCreatedParentNodes()) { 159 for (ITaskTreeNode child : node.getChildren()) { 160 System.out.println(child); 161 } 162 System.out.println(); 163 } 164 165 return appData.getResult(); 204 } 205 206 return count; 207 } 208 209 // /** 210 // * <p> 211 // * TODO: comment 212 // * </p> 213 // * 214 // * @param appData 215 // */ 216 // private void mergeEqualTasks(RuleApplicationData appData) { 217 // System.out.println("merging equal tasks"); 218 // appData.getStopWatch().start("merging equal tasks"); 219 // 220 // int replacements = 0; 221 // List<ISequence> sessions = appData.getSessions(); 222 // 223 // IdentityHashMap<ITaskTreeNode, ITaskTreeNode> replacedChildren = 224 // new IdentityHashMap<ITaskTreeNode, ITaskTreeNode>(); 225 // 226 // for (int sessionIdx1 = 0; sessionIdx1 < sessions.size(); sessionIdx1++) { 227 // List<ITaskTreeNode> children1 = appData.getSessions().get(sessionIdx1).getChildren(); 228 // for (int childIdx1 = 0; childIdx1 < children1.size(); childIdx1++) { 229 // // this is the child of which we search equal other children to merge and to 230 // // replace with one single unique node 231 // ITaskTreeNode child1 = children1.get(childIdx1); 232 // 233 // if (replacedChildren.containsKey(child1)) { 234 // continue; 235 // } 236 // 237 // // now search for all other children that are equal. Also record the session they 238 // // belong to as well as the index in that session 239 // List<ITaskTreeNode> equalChildren = new LinkedList<ITaskTreeNode>(); 240 // List<Integer> sessionIndexes = new LinkedList<Integer>(); 241 // List<Integer> childIndexes = new LinkedList<Integer>(); 242 // 243 // // add all information about the current child 244 // equalChildren.add(child1); 245 // sessionIndexes.add(sessionIdx1); 246 // childIndexes.add(childIdx1); 247 // 248 // for (int sessionIdx2 = sessionIdx1; sessionIdx2 < sessions.size(); sessionIdx2++) { 249 // List<ITaskTreeNode> children2 = 250 // appData.getSessions().get(sessionIdx2).getChildren(); 251 // 252 // int startIndex = (sessionIdx1 == sessionIdx2) ? childIdx1 + 1 : 0; 253 // 254 // for (int childIdx2 = startIndex; childIdx2 < children2.size(); childIdx2++) { 255 // ITaskTreeNode child2 = children2.get(childIdx2); 256 // 257 // if ((child1 != child2) && (nodeComparator.equals(child1, child2))) { 258 // // this is an equal child --> record its occurrence 259 // equalChildren.add(child2); 260 // sessionIndexes.add(sessionIdx2); 261 // childIndexes.add(childIdx2); 262 // } 263 // } 264 // } 265 // 266 // // now merge the found children 267 // if (equalChildren.size() > 1) { 268 // ITaskTreeNode replacement = 269 // mergeVariantsOfTasks(child1.toString(), equalChildren); 270 // 271 // for (int i = 0; i < sessionIndexes.size(); i++) { 272 // taskTreeBuilder.setChild(appData.getSessions().get(sessionIndexes.get(i)), 273 // childIndexes.get(i), replacement); 274 // 275 // replacements++; 276 // } 277 // 278 // // remember the replacement to prevent comparison of merged nodes 279 // replacedChildren.put(replacement, replacement); 280 // 281 // System.out.println 282 // ("replaced " + sessionIndexes.size() + " occurrences of " + child1); 283 // } 284 // } 285 // } 286 // 287 // appData.getStopWatch().stop("merging equal tasks"); 288 // 289 // System.out.println("replaced " + replacements + " equal tasks with unique replacements"); 290 // } 291 // 292 /** 293 * <p> 294 * TODO: comment 295 * </p> 296 * 297 * @param appData 298 */ 299 private void detectAndReplaceTasks(RuleApplicationData appData) { 300 System.out.println("detecting and replacing tasks"); 301 appData.getStopWatch().start("detecting tasks"); 302 303 getSequencesOccuringMostOften(appData); 304 305 appData.getStopWatch().stop("detecting tasks"); 306 appData.getStopWatch().start("replacing tasks"); 307 308 replaceSequencesOccurringMostOften(appData); 309 310 appData.getStopWatch().stop("replacing tasks"); 311 System.out.println("detected and replaced " + appData.getLastFoundTasks().size() + " tasks"); 166 312 } 167 313 … … 174 320 * @return 175 321 */ 176 private void getSequencesOccuringMostOften(RuleApplicationData<ITaskTreeNode> appData) { 177 System.out.println("determining most prominent tasks with a maximum of " + 178 (appData.getLastFoundSequences().getOccurrenceCount() - 1) + 179 " occurrences"); 180 181 Sequences<ITaskTreeNode> sequences; 322 private void getSequencesOccuringMostOften(RuleApplicationData appData) { 323 System.out.println("determining most prominent tasks"); 324 325 Tasks tasks; 182 326 boolean createNewTrie = (appData.getLastTrie() == null) || 183 327 appData.getReplacementCounter() > 0; // tree has changed … … 188 332 } 189 333 190 /*PathDumper dumper = new PathDumper(); 191 trie.process(dumper); 192 193 dumper.dump();*/ 194 195 appData.getStopWatch().start("determining tasks"); 196 197 MaxCountAndLongestSequenceFinder finder = new MaxCountAndLongestSequenceFinder 198 (appData.getLastFoundSequences().getOccurrenceCount() - 1); 334 MaxCountAndLongestTasksFinder finder = new MaxCountAndLongestTasksFinder(); 199 335 appData.getLastTrie().process(finder); 200 336 201 sequences = finder.getFoundSequences();337 tasks = finder.getFoundTasks(); 202 338 203 339 createNewTrie = false; 204 340 205 for (List<ITaskTreeNode> task : sequences) {341 for (List<ITaskTreeNode> task : tasks) { 206 342 if (task.size() >= appData.getTrainedSequenceLength()) { 207 343 // Trie must be recreated with a longer sequence length to be sure that … … 212 348 } 213 349 } 214 215 appData.getStopWatch().stop("determining tasks");216 350 } 217 351 while (createNewTrie); 218 352 219 appData.setLastFoundSequences(sequences); 353 appData.setLastFoundTasks(tasks); 354 355 System.out.println("found " + appData.getLastFoundTasks().size() + " tasks occurring " + 356 appData.getLastFoundTasks().getOccurrenceCount() + " times"); 220 357 } 221 358 … … 228 365 * @return 229 366 */ 230 private void createNewTrie(RuleApplicationData <ITaskTreeNode>appData) {367 private void createNewTrie(RuleApplicationData appData) { 231 368 System.out.println("training trie with a maximum sequence length of " + 232 369 appData.getTrainedSequenceLength()); … … 235 372 appData.setLastTrie(new Trie<ITaskTreeNode>(nodeComparator)); 236 373 237 trainTrie(appData.getTree(), appData); 374 List<ISequence> sessions = appData.getSessions(); 375 376 for (ISequence session : sessions) { 377 trainTrie(session, appData); 378 } 379 238 380 appData.getStopWatch().stop("training trie"); 239 381 } … … 247 389 * @param parent 248 390 */ 249 private void trainTrie(ITaskTreeNode parent, RuleApplicationData<ITaskTreeNode> appData) { 250 // prevent training of already replaces sequences as those shall not be replaced anymore 251 if (!appData.getResult().getNewlyCreatedParentNodes().contains(parent)) { 252 List<ITaskTreeNode> children = parent.getChildren(); 253 254 if ((children != null) && (children.size() > 0)) { 391 private void trainTrie(ISequence session, RuleApplicationData appData) { 392 List<ITaskTreeNode> children = session.getChildren(); 393 394 if ((children != null) && (children.size() > 0)) { 395 appData.getLastTrie().train(children, appData.getTrainedSequenceLength()); 396 } 397 } 398 399 /** 400 * <p> 401 * TODO: comment 402 * </p> 403 * 404 * @param appData 405 */ 406 private void replaceSequencesOccurringMostOften(RuleApplicationData appData) { 407 appData.resetReplacementCounter(); 408 409 if ((appData.getLastFoundTasks().size() > 0) && 410 (appData.getLastFoundTasks().getOccurrenceCount() > 1)) 411 { 412 System.out.println("replacing tasks occurrences with merged variants of all versions"); 413 414 for (List<ITaskTreeNode> task : appData.getLastFoundTasks()) { 415 String taskId = "task " + RuleUtils.getNewId(); 416 System.out.println("replacing " + taskId + ": " + task); 417 418 appData.clearTaskOccurrences(); 419 determineVariantsOfTaskOccurrences(task, appData.getSessions(), appData); 255 420 256 /*System.out.println(); 257 for (int i = 0; i < children.size(); i++) { 258 System.out.println(children.get(i)); 259 }*/ 421 appData.getStopWatch().start("merging task nodes"); 422 ITaskTreeNode taskReplacement = mergeVariantsOfTaskOccurrence(taskId, appData); 423 appData.getStopWatch().stop("merging task nodes"); 424 425 appData.resetReplacementCounter(); 426 replaceTaskOccurrences(task, taskReplacement, appData.getSessions(), appData); 427 428 if (appData.getReplacementCounter() > 0) { 429 appData.getResult().addNewlyCreatedParentNode(taskReplacement); 430 } 431 432 if (appData.getReplacementCounter() < 433 appData.getLastFoundTasks().getOccurrenceCount()) 434 { 435 System.out.println(taskId + ": replaced task only " + 436 appData.getReplacementCounter() + 437 " times instead of expected " + 438 appData.getLastFoundTasks().getOccurrenceCount()); 439 } 440 } 441 } 442 443 } 444 445 /** 446 * <p> 447 * TODO: comment 448 * </p> 449 * 450 * @param tree 451 */ 452 private void determineVariantsOfTaskOccurrences(List<ITaskTreeNode> task, 453 List<ISequence> sessions, 454 RuleApplicationData appData) 455 { 456 for (ISequence session : sessions) { 457 int index = -1; 260 458 261 appData.getLastTrie().train(children, appData.getTrainedSequenceLength()); 262 263 for (ITaskTreeNode child : children) { 264 trainTrie(child, appData); 459 List<ITaskTreeNode> children = session.getChildren(); 460 461 do { 462 index = getSubListIndex(children, task, ++index); 463 464 if (index > -1) { 465 ISequence taskOccurrence = RuleUtils.getSubSequenceInRange 466 (session, index, index + task.size() - 1, null, 467 taskTreeNodeFactory, taskTreeBuilder); 468 469 appData.addTaskOccurrence(taskOccurrence); 470 471 // let the index point to the last element the belongs the identified occurrence 472 index += task.size() - 1; 265 473 } 266 474 } 475 while (index > -1); 476 } 477 } 478 479 /** 480 * <p> 481 * TODO: comment 482 * </p> 483 * 484 * @param appData 485 * @return 486 */ 487 private ITaskTreeNode mergeVariantsOfTaskOccurrence(String taskId, 488 RuleApplicationData appData) 489 { 490 return mergeVariantsOfTasks(taskId, appData.getTaskOccurrences()); 491 } 492 493 /** 494 * <p> 495 * TODO: comment 496 * </p> 497 * 498 * @param appData 499 * @return 500 */ 501 private ITaskTreeNode mergeVariantsOfTasks(String description, List<ITaskTreeNode> variants) { 502 // merge but preserve lexically distinct variants 503 TaskTreeNodeMerger merger = new TaskTreeNodeMerger 504 (taskTreeNodeFactory, taskTreeBuilder, nodeComparator); 505 506 merger.mergeTaskNodes(variants); 507 508 if (variants.size() == 1) { 509 ITaskTreeNode replacement = variants.get(0); 510 taskTreeBuilder.setDescription(replacement, description); 511 return replacement; 512 } 513 else { 514 ISelection selection = taskTreeNodeFactory.createNewSelection(); 515 taskTreeBuilder.setDescription(selection, "variants of task " + description); 516 517 for (ITaskTreeNode variant : variants) { 518 taskTreeBuilder.addChild(selection, variant); 519 } 520 521 return selection; 267 522 } 268 523 } … … 279 534 * @param result 280 535 */ 281 private void createSequenceForTaskOccurrences(String taskId,282 List<ITaskTreeNode> task,283 ITaskTreeNode parent,284 RuleApplicationData<ITaskTreeNode>appData)536 private void replaceTaskOccurrences(List<ITaskTreeNode> task, 537 ITaskTreeNode replacement, 538 List<ISequence> sessions, 539 RuleApplicationData appData) 285 540 { 286 List<ITaskTreeNode> children = parent.getChildren();287 288 if ((children == null) || (children.size() == 0)) {289 return;290 }291 292 // first traverse the children293 for (ITaskTreeNode child : children) {294 createSequenceForTaskOccurrences(taskId, task, child, appData);295 }296 297 541 // now check the children themselves for an occurrence of the task 298 int index = -1; 299 300 do { 301 index = getSubListIndex(children, task, ++index); 302 303 if (index > -1) { 304 if (task.size() < children.size()) { 305 ISequence sequence = RuleUtils.createNewSubSequenceInRange 306 (parent, index, index + task.size() - 1, taskId, 307 taskTreeNodeFactory, taskTreeBuilder); 308 309 appData.getResult().addNewlyCreatedParentNode(sequence); 310 appData.incrementReplacementCounter(); 311 312 children = parent.getChildren(); 313 } 314 else { 315 // the whole list of children is an occurrence of this task. Just set the 316 // description of the parent and break up 317 String description = parent.getDescription(); 318 319 if ((description != null) && (description.length() > 0)) { 320 description += "; " + taskId; 542 for (int i = 0; i < sessions.size(); i++) { 543 ISequence session = sessions.get(i); 544 545 int index = -1; 546 547 List<ITaskTreeNode> children = session.getChildren(); 548 549 do { 550 index = getSubListIndex(children, task, ++index); 551 552 if (index > -1) { 553 if ((!(replacement instanceof ISequence)) || 554 (task.size() < children.size())) 555 { 556 for (int j = index; j < index + task.size(); j++) { 557 taskTreeBuilder.removeChild(session, index); 558 } 559 560 taskTreeBuilder.addChild(session, index, replacement); 561 appData.incrementReplacementCounter(); 562 563 children = session.getChildren(); 321 564 } 322 565 else { 323 description = taskId; 566 // the whole list of children is an occurrence of this task. So ask the 567 // caller of the method to replace the whole node 568 sessions.set(i, (ISequence) replacement); 569 appData.incrementReplacementCounter(); 570 break; 324 571 } 325 326 taskTreeBuilder.setDescription(parent, description);327 break;328 572 } 329 573 } 330 }331 while (index > -1);574 while (index > -1); 575 } 332 576 } 333 577 … … 356 600 break; 357 601 } 358 else if (!nodeComparator.equals(subList.get(j), list.get(i + j))){359 throw new RuntimeException("comparator not commutative");360 }361 602 } 362 603 … … 377 618 * @author Patrick Harms 378 619 */ 379 private class MaxCountAndLongestSequenceFinder implements TrieProcessor<ITaskTreeNode> { 380 381 /** 382 * 383 */ 384 private int maxCount; 620 private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskTreeNode> { 385 621 386 622 /** … … 392 628 * 393 629 */ 394 private List<List<ITaskTreeNode>> found Sequences = new LinkedList<List<ITaskTreeNode>>();630 private List<List<ITaskTreeNode>> foundTasks = new LinkedList<List<ITaskTreeNode>>(); 395 631 396 632 /** … … 401 637 * @param maxCount 402 638 */ 403 public MaxCountAndLongest SequenceFinder(int maxCount) {639 public MaxCountAndLongestTasksFinder() { 404 640 super(); 405 this.maxCount = maxCount;406 641 this.currentCount = 0; 407 642 } … … 411 646 */ 412 647 @Override 413 public TrieProcessor.Result process(List<ITaskTreeNode> sequence, int count) {414 if ( sequence.size() < 2) {648 public TrieProcessor.Result process(List<ITaskTreeNode> task, int count) { 649 if (task.size() < 2) { 415 650 // ignore single nodes 416 651 return TrieProcessor.Result.CONTINUE; … … 422 657 } 423 658 424 if (count > this.maxCount) {425 // ignore sequences that occur too often426 return TrieProcessor.Result.CONTINUE;427 }428 429 659 if (this.currentCount > count) { 430 660 // ignore this children of this node, as they may have only smaller counts than 431 // the already found sequences661 // the already found tasks 432 662 return TrieProcessor.Result.SKIP_NODE; 433 663 } 434 664 435 665 if (this.currentCount < count) { 436 // the provided sequence occurs more often that all sequences found so far.437 // clear all found sequences and use the new count as the one searched for438 found Sequences.clear();666 // the provided task occurs more often that all tasks found so far. 667 // clear all found tasks and use the new count as the one searched for 668 foundTasks.clear(); 439 669 this.currentCount = count; 440 670 } 441 671 442 672 if (this.currentCount == count) { 443 // the sequence is of interest. Sort it into the other found sequences so that673 // the task is of interest. Sort it into the other found tasks so that 444 674 // the longest come first 445 675 boolean added = false; 446 for (int i = 0; i < found Sequences.size(); i++) {447 if (found Sequences.get(i).size() < sequence.size()) {676 for (int i = 0; i < foundTasks.size(); i++) { 677 if (foundTasks.get(i).size() < task.size()) { 448 678 // defensive copy 449 found Sequences.add(i, new LinkedList<ITaskTreeNode>(sequence)); // defensive copy679 foundTasks.add(i, new LinkedList<ITaskTreeNode>(task)); // defensive copy 450 680 added = true; 451 681 break; … … 454 684 455 685 if (!added) { 456 found Sequences.add(new LinkedList<ITaskTreeNode>(sequence)); // defensive copy686 foundTasks.add(new LinkedList<ITaskTreeNode>(task)); // defensive copy 457 687 } 458 688 } … … 468 698 * @return 469 699 */ 470 public Sequences<ITaskTreeNode> getFoundSequences() {700 public Tasks getFoundTasks() { 471 701 removePermutationsOfShorterTasks(); 472 return new Sequences<ITaskTreeNode>(currentCount, foundSequences);702 return new Tasks(currentCount, foundTasks); 473 703 } 474 704 … … 482 712 // now iterate the sorted list and for each task remove all other tasks that are shorter 483 713 // (i.e. come later in the sorted list) and that represent a subpart of the task 484 for (int i = 0; i < found Sequences.size(); i++) {485 for (int j = i + 1; j < found Sequences.size();) {486 if (found Sequences.get(j).size() < foundSequences.get(i).size()) {714 for (int i = 0; i < foundTasks.size(); i++) { 715 for (int j = i + 1; j < foundTasks.size();) { 716 if (foundTasks.get(j).size() < foundTasks.get(i).size()) { 487 717 // found a task that is a potential subtask. Check for this and remove the 488 718 // subtask if needed 489 List<ITaskTreeNode> longTask = found Sequences.get(i);490 List<ITaskTreeNode> shortTask = found Sequences.get(j);719 List<ITaskTreeNode> longTask = foundTasks.get(i); 720 List<ITaskTreeNode> shortTask = foundTasks.get(j); 491 721 492 722 if (getSubListIndex(longTask, shortTask, 0) > -1) { 493 found Sequences.remove(j);723 foundTasks.remove(j); 494 724 } 495 725 else { … … 509 739 * 510 740 */ 511 private class RuleApplicationData<T> { 512 513 /** 514 * 515 */ 516 private T tree; 741 private class RuleApplicationData { 742 743 /** 744 * 745 */ 746 private List<ISequence> sessions; 747 748 /** 749 * 750 */ 751 private Trie<ITaskTreeNode> lastTrie; 752 753 /** 754 * default and minimum trained sequence length is 3 755 */ 756 private int trainedSequenceLength = 3; 757 758 /** 759 * 760 */ 761 private Tasks lastFoundTasks = new Tasks(Integer.MAX_VALUE, null); 762 763 /** 764 * 765 */ 766 private List<ITaskTreeNode> taskOccurrences = new LinkedList<ITaskTreeNode>(); 767 768 /** 769 * 770 */ 771 private int replacementCounter; 517 772 518 773 /** … … 524 779 * 525 780 */ 526 private Sequences<T> lastFoundSequences = new Sequences<T>(Integer.MAX_VALUE, null);527 528 /**529 *530 */531 private Trie<T> lastTrie;532 533 /**534 * default and minimum trained sequence length is 3535 */536 private int trainedSequenceLength = 3;537 538 /**539 *540 */541 private int replacementCounter;542 543 /**544 *545 */546 781 private StopWatch stopWatch = new StopWatch(); 547 782 … … 549 784 * 550 785 */ 551 private RuleApplicationData( T tree) {552 this. tree = tree;553 } 554 555 /** 556 * @return the lastFoundSequences557 */ 558 private Sequences<T> getLastFoundSequences() {559 return lastFoundSequences;560 } 561 562 /** 563 * @param last FoundSequences the lastFoundSequencesto set564 */ 565 private void setLast FoundSequences(Sequences<T> lastFoundSequences) {566 this.last FoundSequences = lastFoundSequences;786 private RuleApplicationData(List<ISequence> sessions) { 787 this.sessions = sessions; 788 } 789 790 /** 791 * @return the tree 792 */ 793 private List<ISequence> getSessions() { 794 return sessions; 795 } 796 797 /** 798 * @param lastTrie the lastTrie to set 799 */ 800 private void setLastTrie(Trie<ITaskTreeNode> lastTrie) { 801 this.lastTrie = lastTrie; 567 802 } 568 803 … … 570 805 * @return the lastTrie 571 806 */ 572 private Trie< T> getLastTrie() {807 private Trie<ITaskTreeNode> getLastTrie() { 573 808 return lastTrie; 809 } 810 811 /** 812 * @param trainedSequenceLength the trainedSequenceLength to set 813 */ 814 private void setTrainedSequenceLength(int trainedSequenceLength) { 815 this.trainedSequenceLength = trainedSequenceLength; 574 816 } 575 817 … … 582 824 583 825 /** 584 * @param trainedSequenceLength the trainedSequenceLength to set 585 */ 586 private void setTrainedSequenceLength(int trainedSequenceLength) { 587 this.trainedSequenceLength = trainedSequenceLength; 588 } 589 590 /** 591 * @param lastTrie the lastTrie to set 592 */ 593 private void setLastTrie(Trie<T> lastTrie) { 594 this.lastTrie = lastTrie; 595 } 596 597 /** 598 * @return the tree 599 */ 600 private T getTree() { 601 return tree; 602 } 603 826 * @param lastFoundSequences the lastFoundSequences to set 827 */ 828 private void setLastFoundTasks(Tasks lastFoundSequences) { 829 this.lastFoundTasks = lastFoundSequences; 830 } 831 832 /** 833 * @return the lastFoundSequences 834 */ 835 private Tasks getLastFoundTasks() { 836 return lastFoundTasks; 837 } 838 839 /** 840 * @return the taskOccurrences 841 */ 842 private void clearTaskOccurrences() { 843 taskOccurrences.clear(); 844 } 845 846 /** 847 * @return the taskOccurrences 848 */ 849 private void addTaskOccurrence(ITaskTreeNode taskOccurrence) { 850 taskOccurrences.add(taskOccurrence); 851 } 852 853 /** 854 * @return the taskOccurrences 855 */ 856 private List<ITaskTreeNode> getTaskOccurrences() { 857 return taskOccurrences; 858 } 859 860 /** 861 * 862 */ 863 private void resetReplacementCounter() { 864 replacementCounter = 0; 865 } 866 867 /** 868 * 869 */ 870 private void incrementReplacementCounter() { 871 replacementCounter++; 872 } 873 874 /** 875 * 876 */ 877 private int getReplacementCounter() { 878 return replacementCounter; 879 } 880 604 881 /** 605 882 * @return the result … … 616 893 } 617 894 618 /**619 *620 */621 private void resetReplacementCounter() {622 replacementCounter = 0;623 }624 625 /**626 *627 */628 private void incrementReplacementCounter() {629 replacementCounter++;630 }631 632 /**633 *634 */635 private int getReplacementCounter() {636 return replacementCounter;637 }638 895 } 639 896 … … 646 903 * @author Patrick Harms 647 904 */ 648 private class Sequences<T> implements Iterable<List<T>> {905 private class Tasks implements Iterable<List<ITaskTreeNode>> { 649 906 650 907 /** … … 656 913 * 657 914 */ 658 private List<List< T>> sequences;915 private List<List<ITaskTreeNode>> sequences; 659 916 660 917 /** … … 666 923 * @param sequences 667 924 */ 668 private Sequences(int occurrenceCount, List<List<T>> sequences) {925 private Tasks(int occurrenceCount, List<List<ITaskTreeNode>> sequences) { 669 926 super(); 670 927 this.occurrenceCount = occurrenceCount; … … 702 959 */ 703 960 @Override 704 public Iterator<List< T>> iterator() {961 public Iterator<List<ITaskTreeNode>> iterator() { 705 962 return this.sequences.iterator(); 706 963 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnGuiElementDetectionRule.java
r1117 r1127 34 34 * @author 2012, last modified by $Author: patrick$ 35 35 */ 36 class DefaultGuiElementSequenceDetectionRule implements TemporalRelationshipRule {36 class SequenceOnGuiElementDetectionRule implements TemporalRelationshipRule { 37 37 38 38 /** … … 70 70 * the temporal relationships identified during rule application 71 71 */ 72 DefaultGuiElementSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,73 72 SequenceOnGuiElementDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory, 73 ITaskTreeBuilder taskTreeBuilder) 74 74 { 75 75 this(null, taskTreeNodeFactory, taskTreeBuilder); … … 90 90 * the temporal relationships identified during rule application 91 91 */ 92 DefaultGuiElementSequenceDetectionRule(List<Class<? extends IGUIElement>> guiElementFilter,92 SequenceOnGuiElementDetectionRule(List<Class<? extends IGUIElement>> guiElementFilter, 93 93 ITaskTreeNodeFactory taskTreeNodeFactory, 94 94 ITaskTreeBuilder taskTreeBuilder) … … 104 104 @Override 105 105 public String toString() { 106 return " DefaultGuiElementSequenceDetectionRule";106 return "SequenceOnGuiElementDetectionRule"; 107 107 } 108 108 … … 154 154 155 155 if (status == null) { 156 status = RuleApplicationStatus. RULE_NOT_APPLIED;156 status = RuleApplicationStatus.NOT_APPLIED; 157 157 } 158 158 … … 193 193 int startingIndex = -1; 194 194 195 RuleApplicationStatus status = RuleApplicationStatus. RULE_NOT_APPLIED;195 RuleApplicationStatus status = RuleApplicationStatus.NOT_APPLIED; 196 196 boolean subsequenceHasStarted = false; 197 197 boolean exceedingGuiHierarchyDepth = false; … … 202 202 203 203 int index = 0; 204 while (index < parent.getChildren().size()) { 204 List<ITaskTreeNode> children = parent.getChildren(); 205 206 while (index < children.size()) { 205 207 hierarchy = hierarchies.get(index); 206 208 … … 220 222 status = condenseSequence 221 223 (parent, hierarchies, hierarchyLevel, startingIndex, index - 1, result); 224 225 // children may have changed, retrieve them again. 226 children = parent.getChildren(); 222 227 223 228 if (status != null) { … … 244 249 status = condenseSequence 245 250 (parent, hierarchies, hierarchyLevel, startingIndex, 246 parent.getChildren().size() - 1, result);247 } 248 else if (status != RuleApplicationStatus. RULE_APPLICATION_FINISHED) {249 status = RuleApplicationStatus. RULE_NOT_APPLIED;251 children.size() - 1, result); 252 } 253 else if (status != RuleApplicationStatus.FINISHED) { 254 status = RuleApplicationStatus.NOT_APPLIED; 250 255 } 251 256 } 252 257 else { 253 if ((currentParent != null) && 254 (status != RuleApplicationStatus.RULE_APPLICATION_FINISHED)) 255 { 256 status = RuleApplicationStatus.RULE_APPLICATION_FEASIBLE; 258 if ((currentParent != null) && (status != RuleApplicationStatus.FINISHED)) { 259 status = RuleApplicationStatus.FEASIBLE; 257 260 } 258 261 } … … 288 291 { 289 292 boolean onlyASingleChildToReduce = (endIndex - startIndex) == 0; 293 294 List<ITaskTreeNode> children = parent.getChildren(); 295 290 296 boolean singleChildIsSequence = onlyASingleChildToReduce && 291 parent.getChildren().get(startIndex) instanceof ISequence;297 children.get(startIndex) instanceof ISequence; 292 298 293 299 if (!onlyASingleChildToReduce || !singleChildIsSequence) { … … 302 308 303 309 for (int i = startIndex; i <= endIndex; i++) { 304 taskTreeBuilder.addChild(sequence, parent.getChildren().get(startIndex));310 taskTreeBuilder.addChild(sequence, children.get(startIndex)); 305 311 taskTreeBuilder.removeChild((ISequence) parent, startIndex); 306 312 … … 316 322 result.addNewlyCreatedParentNode(sequence); 317 323 318 return RuleApplicationStatus. RULE_APPLICATION_FINISHED;324 return RuleApplicationStatus.FINISHED; 319 325 } 320 326 else { -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceOnSameTargetDetectionRule.java
r1117 r1127 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 16 17 import java.util.List; 18 17 19 import de.ugoe.cs.autoquest.eventcore.IEventTarget; 18 20 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; … … 29 31 * @author 2012, last modified by $Author: patrick$ 30 32 */ 31 class DefaultEventTargetSequenceDetectionRule implements TemporalRelationshipRule {33 class SequenceOnSameTargetDetectionRule implements TemporalRelationshipRule { 32 34 33 35 /** … … 58 60 * the temporal relationships identified during rule application 59 61 */ 60 DefaultEventTargetSequenceDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory,61 62 SequenceOnSameTargetDetectionRule(ITaskTreeNodeFactory taskTreeNodeFactory, 63 ITaskTreeBuilder taskTreeBuilder) 62 64 { 63 65 this.taskTreeNodeFactory = taskTreeNodeFactory; … … 70 72 @Override 71 73 public String toString() { 72 return " DefaultEventTargetSequenceDetectionRule";74 return "SequenceOnSameTargetDetectionRule"; 73 75 } 74 76 … … 91 93 92 94 int index = 0; 93 while (index < parent.getChildren().size()) { 94 ITaskTreeNode child = parent.getChildren().get(index); 95 List<ITaskTreeNode> children = parent.getChildren(); 96 97 while (index < children.size()) { 98 ITaskTreeNode child = children.get(index); 95 99 96 100 IEventTarget eventTarget = determineEventTarget(child); … … 109 113 // or if this child is not a sequence itself 110 114 if ((startingIndex != endIndex) || 111 (!( parent.getChildren().get(startingIndex) instanceof ISequence)))115 (!(children.get(startingIndex) instanceof ISequence))) 112 116 { 113 117 handleEventTargetSequence 114 118 (parent, currentEventTarget, startingIndex, endIndex, result); 115 119 116 result.setRuleApplicationStatus 117 (RuleApplicationStatus.RULE_APPLICATION_FINISHED); 120 result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 118 121 return result; 119 122 } … … 134 137 135 138 if (startingIndex > -1) { 136 int endIndex = parent.getChildren().size() - 1;139 int endIndex = children.size() - 1; 137 140 138 141 if (finalize) { … … 141 144 if ((startingIndex > 0) && 142 145 ((startingIndex != endIndex) || 143 (!( parent.getChildren().get(startingIndex) instanceof ISequence))))146 (!(children.get(startingIndex) instanceof ISequence)))) 144 147 { 145 148 handleEventTargetSequence 146 149 (parent, currentEventTarget, startingIndex, endIndex, result); 147 150 148 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FINISHED);151 result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 149 152 } 150 153 } 151 154 else { 152 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);155 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 153 156 } 154 157 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskTreeNodeComparator.java
r1107 r1127 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 16 17 import java.util.HashMap; 18 17 19 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 18 20 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; … … 44 46 private NodeEquality minimalNodeEquality; 45 47 46 48 private Comparer comparer; 49 50 private Comparer lexicalComparer; 51 52 private StopWatch stopWatch = new StopWatch(); 53 54 private HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>(); 55 56 private HashMap<Long, Boolean> lexicalEqualityBuffer; 47 57 48 58 /** … … 60 70 this.nodeEqualityRuleManager = nodeEqualityRuleManager; 61 71 this.minimalNodeEquality = minimalNodeEquality; 62 } 63 64 72 73 if (minimalNodeEquality == NodeEquality.LEXICALLY_EQUAL) { 74 comparer = new LexicalComparer(); 75 } 76 else if (minimalNodeEquality == NodeEquality.SYNTACTICALLY_EQUAL) { 77 comparer = new SyntacticalComparer(); 78 } 79 else if (minimalNodeEquality == NodeEquality.SEMANTICALLY_EQUAL) { 80 comparer = new SemanticalComparer(); 81 } 82 else { 83 comparer = new DefaultComparer(); 84 } 85 86 if (minimalNodeEquality == NodeEquality.LEXICALLY_EQUAL) { 87 lexicalComparer = comparer; 88 lexicalEqualityBuffer = equalityBuffer; 89 } 90 else { 91 lexicalComparer = new LexicalComparer(); 92 lexicalEqualityBuffer = new HashMap<Long, Boolean>(); 93 } 94 } 65 95 66 96 /* (non-Javadoc) … … 69 99 @Override 70 100 public boolean equals(ITaskTreeNode symbol1, ITaskTreeNode symbol2) { 71 return nodeEqualityRuleManager.applyRules(symbol1, symbol2).isAtLeast(minimalNodeEquality); 72 } 73 101 //String id = "compare " + symbol1.getClass().getSimpleName() + " " + 102 // symbol2.getClass().getSimpleName(); 103 //String id = "compare"; 104 //stopWatch.start(id); 105 106 Boolean result; 107 108 if (symbol1 != symbol2) { 109 long key = ((long) System.identityHashCode(symbol1)) << 32; 110 key += System.identityHashCode(symbol2); 111 112 result = equalityBuffer.get(key); 113 114 if (result == null) { 115 result = comparer.compare(symbol1, symbol2); 116 equalityBuffer.put(key, result); 117 } 118 } 119 else { 120 result = true; 121 } 122 //stopWatch.stop(id); 123 124 /*boolean result2 = nodeEqualityRuleManager.areAtLeastEqual(symbol1, symbol2, minimalNodeEquality); 125 if (result != result2) { 126 throw new IllegalStateException("implementation error"); 127 }*/ 128 129 return result; 130 } 131 132 /** 133 * <p> 134 * TODO: comment 135 * </p> 136 * 137 * @return 138 */ 139 StopWatch getStopWatch() { 140 return stopWatch; 141 } 142 143 /** 144 * <p> 145 * TODO: comment 146 * </p> 147 * 148 * @param node1 149 * @param node2 150 * @return 151 */ 152 boolean areLexicallyEqual(ITaskTreeNode symbol1, ITaskTreeNode symbol2) { 153 Boolean result; 154 155 if (symbol1 != symbol2) { 156 long key = ((long) System.identityHashCode(symbol1)) << 32; 157 key += System.identityHashCode(symbol2); 158 159 result = lexicalEqualityBuffer.get(key); 160 161 if (result == null) { 162 result = lexicalComparer.compare(symbol1, symbol2); 163 lexicalEqualityBuffer.put(key, result); 164 } 165 } 166 else { 167 result = true; 168 } 169 170 return result; 171 } 172 173 /** 174 * <p> 175 * TODO: comment 176 * </p> 177 * 178 * @return 179 */ 180 NodeEquality getConsideredNodeEquality() { 181 return minimalNodeEquality; 182 } 183 184 /** 185 * 186 */ 187 private interface Comparer { 188 /** 189 * 190 */ 191 boolean compare(ITaskTreeNode node1, ITaskTreeNode node2); 192 } 193 194 /** 195 * 196 */ 197 private class LexicalComparer implements Comparer { 198 199 /** 200 * 201 */ 202 public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) { 203 return nodeEqualityRuleManager.areLexicallyEqual(node1, node2); 204 } 205 } 206 207 /** 208 * 209 */ 210 private class SyntacticalComparer implements Comparer { 211 212 /** 213 * 214 */ 215 public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) { 216 return nodeEqualityRuleManager.areSyntacticallyEqual(node1, node2); 217 } 218 } 219 220 /** 221 * 222 */ 223 private class SemanticalComparer implements Comparer { 224 225 /** 226 * 227 */ 228 public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) { 229 return nodeEqualityRuleManager.areSemanticallyEqual(node1, node2); 230 } 231 } 232 233 /** 234 * 235 */ 236 private class DefaultComparer implements Comparer { 237 238 /** 239 * 240 */ 241 public boolean compare(ITaskTreeNode node1, ITaskTreeNode node2) { 242 return nodeEqualityRuleManager.areAtLeastEqual(node1, node2, minimalNodeEquality); 243 } 244 } 74 245 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java
r1113 r1127 157 157 158 158 treeScopeRules = new TemporalRelationshipRule[] { 159 new SequenceForTaskDetectionRule 160 (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 161 taskTreeNodeFactory, taskTreeBuilder), 162 /*new DefaultTaskSequenceDetectionRule 163 (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 164 taskTreeNodeFactory, taskTreeBuilder), 159 165 new DefaultTaskSequenceDetectionRule 160 (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 161 taskTreeNodeFactory, taskTreeBuilder) 166 (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 167 taskTreeNodeFactory, taskTreeBuilder),*/ 168 /*new TreeScopeWrapperRule 169 (new DefaultIterationDetectionRule 170 (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 171 taskTreeNodeFactory, taskTreeBuilder)), 172 new TreeScopeWrapperRule 173 (new DefaultIterationDetectionRule 174 (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 175 taskTreeNodeFactory, taskTreeBuilder)), 176 new TreeScopeWrapperRule 177 (new DefaultIterationDetectionRule 178 (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 179 taskTreeNodeFactory, taskTreeBuilder))*/ 162 180 }; 163 181 … … 165 183 166 184 nodeScopeRules = new TemporalRelationshipRule[] { 167 //new DefaultGuiElementSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),168 //new DefaultEventTargetSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder),185 //new SequenceOnGuiElementDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 186 //new EventSequenceOnSameTargetDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 169 187 new TrackBarSelectionDetectionRule 170 188 (nodeEqualityRuleManager, taskTreeNodeFactory, taskTreeBuilder), 171 189 //new DefaultGuiEventSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 172 new DefaultIterationDetectionRule173 (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL,174 taskTreeNodeFactory, taskTreeBuilder),175 new DefaultIterationDetectionRule176 (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL,177 taskTreeNodeFactory, taskTreeBuilder),178 new DefaultIterationDetectionRule179 (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL,180 taskTreeNodeFactory, taskTreeBuilder)181 190 }; 182 191 … … 245 254 246 255 if ((result != null) && 247 (result.getRuleApplicationStatus() == 248 RuleApplicationStatus.RULE_APPLICATION_FINISHED)) 256 (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) 249 257 { 250 258 Console.traceln … … 252 260 noOfRuleApplications++; 253 261 254 dumpTask(parent, "");262 //dumpTask(parent, ""); 255 263 256 264 for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { … … 261 269 } 262 270 while ((result != null) && 263 (result.getRuleApplicationStatus() == 264 RuleApplicationStatus.RULE_APPLICATION_FINISHED)); 271 (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 265 272 266 273 if ((!finalize) && 267 274 (result != null) && 268 (result.getRuleApplicationStatus() == 269 RuleApplicationStatus.RULE_APPLICATION_FEASIBLE)) 275 (result.getRuleApplicationStatus() == RuleApplicationStatus.FEASIBLE)) 270 276 { 271 277 // in this case, don't go on applying rules, which should not be applied yet … … 275 281 276 282 if (noOfRuleApplications <= 0) { 277 Console.traceln(Level. INFO, logIndent + "no rules applied --> no temporal " +283 Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " + 278 284 "relationship generated"); 279 285 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TrackBarSelectionDetectionRule.java
r1117 r1127 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 16 17 import java.util.List; 18 17 19 import de.ugoe.cs.autoquest.eventcore.gui.ValueSelection; 18 20 import de.ugoe.cs.autoquest.eventcore.guimodel.ITrackBar; 19 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;20 21 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; 21 22 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; … … 97 98 98 99 int index = 0; 99 while (index < parent.getChildren().size()) { 100 ITaskTreeNode child = parent.getChildren().get(index); 100 List<ITaskTreeNode> children = parent.getChildren(); 101 102 while (index < children.size()) { 103 ITaskTreeNode child = children.get(index); 101 104 102 105 if ((child instanceof IEventTask) && … … 128 131 if (finalize) { 129 132 handleValueSelections(parent, currentTrackBar, valueSelectionStartIndex, 130 parent.getChildren().size() - 1, result);133 children.size() - 1, result); 131 134 } 132 135 else { 133 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FEASIBLE);136 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 134 137 } 135 138 } … … 156 159 taskTreeBuilder.setChild(iteration, selection); 157 160 161 List<ITaskTreeNode> children = parent.getChildren(); 162 158 163 for (int i = endIndex - startIndex; i >= 0; i--) { 159 addChildIfNecessary(selection, parent.getChildren().get(startIndex), result);164 addChildIfNecessary(selection, children.get(startIndex), result); 160 165 taskTreeBuilder.removeChild((ISequence) parent, startIndex); 161 166 } … … 163 168 taskTreeBuilder.addChild((ISequence) parent, startIndex, iteration); 164 169 165 result.setRuleApplicationStatus(RuleApplicationStatus. RULE_APPLICATION_FINISHED);170 result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 166 171 } 167 172 … … 173 178 RuleApplicationResult result) 174 179 { 175 for (int i = 0; i < parentSelection.getChildren().size(); i++) { 176 ITaskTreeNode child = parentSelection.getChildren().get(i); 180 List<ITaskTreeNode> children = parentSelection.getChildren(); 181 182 for (int i = 0; i < children.size(); i++) { 183 ITaskTreeNode child = children.get(i); 177 184 178 185 // check, if the new node is a variant for the current event task 179 NodeEquality nodeEquality = nodeEqualityRuleManager.applyRules(child, node); 180 if (nodeEquality.isAtLeast(NodeEquality.SYNTACTICALLY_EQUAL)) { 186 if (nodeEqualityRuleManager.areSyntacticallyEqual(child, node)) { 181 187 return; 182 188 } -
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TreeScopeWrapperRule.java
r1119 r1127 14 14 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 17 import java.util.List; 16 18 17 19 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; … … 69 71 result = new RuleApplicationResult(); 70 72 71 if (parent.getChildren() != null) { 72 for (ITaskTreeNode child : parent.getChildren()) { 73 List<ITaskTreeNode> children = parent.getChildren(); 74 if (children != null) { 75 for (ITaskTreeNode child : children) { 73 76 merge(result, apply(child, finalize)); 74 77 } … … 97 100 RuleApplicationStatus intermediateStatus = intermediate.getRuleApplicationStatus(); 98 101 99 if ((intermediateStatus == RuleApplicationStatus. RULE_APPLICATION_FINISHED) ||100 ((intermediateStatus == RuleApplicationStatus. RULE_APPLICATION_FEASIBLE) &&101 (overallStatus == RuleApplicationStatus. RULE_NOT_APPLIED)))102 if ((intermediateStatus == RuleApplicationStatus.FINISHED) || 103 ((intermediateStatus == RuleApplicationStatus.FEASIBLE) && 104 (overallStatus == RuleApplicationStatus.NOT_APPLIED))) 102 105 { 103 106 overallResult.setRuleApplicationStatus(intermediateStatus);
Note: See TracChangeset
for help on using the changeset viewer.