Changeset 1954 for trunk/autoquest-core-tasktrees
- Timestamp:
- 05/31/15 19:22:54 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/utils/SimilarTasks.java
r1890 r1954 27 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 28 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 29 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional ;31 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance; 31 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 33 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance; 34 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance; 33 35 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 34 36 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; … … 344 346 public List<TaskPath> getPathsToIgnore() { 345 347 List<TaskPath> result = new LinkedList<TaskPath>(); 346 Delta singleChangeDelta = null;347 348 348 349 if ((patch.getDeltas().size() == 1) && 349 350 (patch.getDeltas().get(0).getType() == Delta.TYPE.CHANGE)) 350 351 { 351 singleChangeDelta = patch.getDeltas().get(0); 352 } 353 354 // if it is a full change, then the parent of either side must be fully ignored 355 if (singleChangeDelta != null) { 352 // if it is a full change, then the parent of either side must be fully ignored 353 Delta singleChangeDelta = patch.getDeltas().get(0); 354 356 355 if ((singleChangeDelta.getOriginal().getPosition() == 0) && 357 356 (singleChangeDelta.getOriginal().size() == leftHandSideTraversal.size())) … … 372 371 373 372 if (result.size() < 2) { 374 // if we do not already ignore both root tasks, check for selections and interleaving 375 // iterations that have to be ignored if they belong to a delta 373 // if we do not already ignore both root tasks, check for overlapping 374 // iterations that are executed multiple times for the tasks to be merged as they have 375 // to be ignored 376 result.addAll(getConflictingIterations()); 377 378 // then check for tasks fully inside delta, which can be preserved 376 379 for (Delta delta : patch.getDeltas()) { 377 //getSelections(delta, result);378 getPathsToRealIntersectingIterations(delta, result);379 380 getNotFullyInterleavingIteration(delta, result); 380 381 getPathsToParentTasksFullyInsideDelta(delta, result); 381 382 } 382 383 383 // check for any parent optional that may be empty and can hence not be flattened 384 TaskPath tmppath = new TaskPath(); 385 tmppath.add(leftHandSide, 0); 386 getParentOptionals(tmppath, result); 387 tmppath = new TaskPath(); 388 tmppath.add(rightHandSide, 0); 389 getParentOptionals(tmppath, result); 384 // check for any parent optional that are at least once empty in instances of the 385 // tasks to be merged and that can, hence, not be flattened 386 getUnexecutedParentOptionals(leftHandSide, result); 387 getUnexecutedParentOptionals(rightHandSide, result); 390 388 391 389 // check if there are common subtasks on both sides that lie outside any delta and … … 839 837 } 840 838 }*/ 841 842 /** 843 * 844 */ 845 @SuppressWarnings("unchecked") 846 private void getPathsToRealIntersectingIterations(Delta delta, List<TaskPath> paths) { 847 TaskPath path1 = getCommonPath((List<TaskPath>) delta.getOriginal().getLines()); 848 TaskPath path2 = getCommonPath((List<TaskPath>) delta.getRevised().getLines()); 849 850 // both paths denote those parent tasks that contain the delta. 851 // But there may be parent tasks still contained in the path that are iterations and 852 // that are disjoint with a parent in the other path. Those iterations need to be 853 // considered, as otherwise a created selection would be against the associative law of 854 // iterations. Hence, we search for the topmost iteration on both paths that is disjoint 855 // with a parent node in the respective other path. 856 857 for (int i = 0; i < path1.size(); i++) { 858 TaskPath path1Prefix = path1.subPath(0, i + 1); 859 int[] idxsPath1 = leftHandSideTraversal.getIndexesRootedBy(path1Prefix); 860 861 // normalize the indexes to be 0 the index of the delta. Everything left of it 862 // is smaller 0, everything right of it, larger. 863 idxsPath1[0] -= delta.getOriginal().getPosition(); 864 idxsPath1[1] -= delta.getOriginal().getPosition() + delta.getOriginal().size() - 1; 865 866 for (int j = 0; j < path2.size(); j++) { 867 TaskPath path2Prefix = path2.subPath(0, j + 1); 868 int[] idxsPath2 = rightHandSideTraversal.getIndexesRootedBy(path2Prefix); 869 870 // normalize the indexes to be 0 the index of the delta. Everything left of it 871 // is smaller 0, everything right of it, larger. 872 idxsPath2[0] -= delta.getRevised().getPosition(); 873 idxsPath2[1] -= 874 delta.getRevised().getPosition() + delta.getRevised().size() - 1; 875 876 // now compare the indexes and check, if the sublists are real subsets of each 877 // other. If not, they only have a real common subset but there is at least one 878 // non shared element on both sides. If so, and one is an iteration, we 879 // have to use it as elements to be selected 880 if (((idxsPath1[0] < idxsPath2[0]) && (idxsPath1[1] < idxsPath2[1])) || 881 ((idxsPath1[0] > idxsPath2[0]) && (idxsPath1[1] > idxsPath2[1]))) 882 { 883 if ((path1.get(i).getTask() instanceof IIteration) && 884 (path2.get(j).getTask() instanceof IIteration)) 885 { 886 // System.out.println("found paths to real intersecting parents"); 887 // int[] indexBuf = leftHandSideTraversal.getIndexesRootedBy(path1Prefix); 888 // System.out.println(idxsPath1[0] + "(" + indexBuf[0] + ") " + idxsPath1[1] + 889 // "(" + indexBuf[1] + ") " + path1Prefix); 890 // indexBuf = rightHandSideTraversal.getIndexesRootedBy(path2Prefix); 891 // System.out.println(idxsPath2[0] + "(" + indexBuf[0] + ") " + idxsPath2[1] + 892 // "(" + indexBuf[1] + ") " + path2Prefix); 839 840 /** 841 * conflicting iterations are those that belong to either side of the sequence pair, that cover 842 * at least two actions, and that were executed multiple times in the context of the tasks 843 * to be merged. Iterations do only conflict, if there are at least two, one belonging to the 844 * left hand side, and the other to the right hand side. They conflict only, if they cover the 845 * same terminal nodes in the task traversals. 846 */ 847 private List<TaskPath> getConflictingIterations() { 848 List<TaskPath> iterationsWithMultipleExecutions = new LinkedList<>(); 849 getIterationsWithMultipleExecutions(leftHandSide, iterationsWithMultipleExecutions); 850 851 if (iterationsWithMultipleExecutions.size() > 0) { 852 // only, if iterations are executed in both side, they are of interest. Hence, 853 // check right hand side only, if left hand side contains repeated iterations. 854 int noOfLeftHandSideRepeatedIterations = iterationsWithMultipleExecutions.size(); 855 getIterationsWithMultipleExecutions(rightHandSide, iterationsWithMultipleExecutions); 856 857 if (iterationsWithMultipleExecutions.size() > noOfLeftHandSideRepeatedIterations) { 858 // also the right hand side contains problematic iterations. Check if they are 859 // overlapping and drop all which are not. 860 dropNonOverlappingIterations(iterationsWithMultipleExecutions); 861 } 862 else { 863 // no conflict, clear the list 864 iterationsWithMultipleExecutions.clear(); 865 } 866 } 867 868 return iterationsWithMultipleExecutions; 869 } 870 871 /** 872 * 873 */ 874 private void getIterationsWithMultipleExecutions(ITask task, 875 List<TaskPath> result) 876 { 877 for (ITaskInstance instance : task.getInstances()) { 878 TaskPath taskPath = new TaskPath(); 879 taskPath.add(task, 0); 880 getIterationsWithMultipleExecutions(instance, taskPath, result); 881 } 882 } 883 884 /** 885 * 886 */ 887 private void getIterationsWithMultipleExecutions(ITaskInstance instance, 888 TaskPath currentPath, 889 List<TaskPath> result) 890 { 891 if (instance instanceof IIterationInstance) { 892 if (((IIterationInstance) instance).size() > 1) { 893 // iteration executed multiple times --> store path 894 result.add(currentPath.subPath(0, currentPath.size())); // ensure to create a copy 895 } 896 897 currentPath.add(((IIteration) instance.getTask()).getMarkedTask(), 0); 898 899 for (ITaskInstance child : (IIterationInstance) instance) { 900 getIterationsWithMultipleExecutions(child, currentPath, result); 901 } 902 903 currentPath.removeLast(); 904 } 905 else if (instance instanceof ISequenceInstance) { 906 int index = 0; 907 for (ITaskInstance child : (ISequenceInstance) instance) { 908 currentPath.add(child.getTask(), index++); 909 getIterationsWithMultipleExecutions(child, currentPath, result); 910 currentPath.removeLast(); 911 } 912 } 913 else if (instance instanceof ISelectionInstance) { 914 ITaskInstance child = ((ISelectionInstance) instance).getChild(); 915 currentPath.add(child.getTask(), 0); 916 getIterationsWithMultipleExecutions(child, currentPath, result); 917 currentPath.removeLast(); 918 } 919 else if (instance instanceof IOptionalInstance) { 920 ITaskInstance child = ((IOptionalInstance) instance).getChild(); 921 if (child != null) { 922 currentPath.add(child.getTask(), 0); 923 getIterationsWithMultipleExecutions(child, currentPath, result); 924 currentPath.removeLast(); 925 } 926 } 927 } 928 929 /** 930 * 931 */ 932 private void dropNonOverlappingIterations(List<TaskPath> iterationsWithMultipleExecutions) { 933 // to check overlappings, iterate the iterations. Then check for each the indexes it covers 934 // in its respective traversal. Adapt the indexes depending on deltas that an iteration 935 // covers. Then check all other iterations. Consider also here the indexes in the traversal. 936 // also here, the indexes must be adapted in case of covered deltas. 937 List<TaskPath> overlappingIterations = new LinkedList<TaskPath>(); 938 939 for (TaskPath leftPath : iterationsWithMultipleExecutions) { 940 if (leftPath.getTask(0).equals(leftHandSide)) { 941 int[] leftIdxs = leftHandSideTraversal.getIndexesRootedBy(leftPath); 942 943 for (TaskPath rightPath : iterationsWithMultipleExecutions) { 944 if (rightPath.getTask(0).equals(rightHandSide)) { 945 int[] rightIdxs = rightHandSideTraversal.getIndexesRootedBy(rightPath); 893 946 894 paths.add(path1Prefix); 895 paths.add(path2Prefix); 896 return; 897 } 898 } 899 } 900 } 947 adaptIndexesBasedOnDeltas(leftIdxs, rightIdxs, patch.getDeltas()); 948 949 if (((leftIdxs[0] < rightIdxs[0]) && (rightIdxs[0] <= leftIdxs[1])) || 950 ((rightIdxs[0] < leftIdxs[0]) && (leftIdxs[0] <= rightIdxs[1]))) 951 { 952 overlappingIterations.add(leftPath); 953 overlappingIterations.add(rightPath); 954 } 955 } 956 } 957 } 958 } 959 960 iterationsWithMultipleExecutions.retainAll(overlappingIterations); 961 } 962 963 /** 964 * 965 */ 966 private void adaptIndexesBasedOnDeltas(int[] originalIndexes, 967 int[] revisedIndexes, 968 List<Delta> deltas) 969 { 970 int originalStartUpdate = 0; 971 int originalEndUpdate = 0; 972 int revisedStartUpdate = 0; 973 int revisedEndUpdate = 0; 974 975 for (Delta delta : deltas) { 976 if (delta.getOriginal().getPosition() < originalIndexes[0]) { 977 originalStartUpdate += delta.getRevised().size(); 978 } 979 if (delta.getOriginal().getPosition() < originalIndexes[1]) { 980 originalEndUpdate += delta.getRevised().size(); 981 } 982 if (delta.getRevised().getPosition() < revisedIndexes[0]) { 983 revisedStartUpdate += delta.getOriginal().size(); 984 } 985 if (delta.getRevised().getPosition() < revisedIndexes[1]) { 986 revisedEndUpdate += delta.getOriginal().size(); 987 } 988 } 989 990 originalIndexes[0] += originalStartUpdate; 991 originalIndexes[1] += originalEndUpdate; 992 revisedIndexes[0] += revisedStartUpdate; 993 revisedIndexes[1] += revisedEndUpdate; 901 994 } 902 995 … … 939 1032 /** 940 1033 * If a chunk has a minimum number of 2 entries and at least one of them belongs to an iteration 941 * th edoes not cover the other and also expands to preceding or succeeding paths in the942 * traversal, we can no merge the situation.1034 * that does not cover the other and also expands to preceding or succeeding paths in the 1035 * traversal, we can not merge the situation. 943 1036 */ 944 1037 private void getNotFullyInterleavingIterations(Chunk chunk, … … 1031 1124 * 1032 1125 */ 1033 private void getParentOptionals(TaskPath taskPath, List<TaskPath> result) { 1034 ITask task = taskPath.getLast(); 1035 1036 if (task instanceof IOptional) { 1037 result.add(new TaskPath(taskPath)); 1038 } 1039 else if (task instanceof ISequence) { 1040 for (int i = 0; i < ((ISequence) task).getChildren().size(); i++) { 1041 taskPath.add(((ISequence) task).getChildren().get(i), i); 1042 getParentOptionals(taskPath, result); 1043 taskPath.removeLast(); 1044 } 1045 } 1046 else if (task instanceof ISelection) { 1047 for (int i = 0; i < ((ISelection) task).getChildren().size(); i++) { 1048 taskPath.add(((ISelection) task).getChildren().get(i), 0); 1049 getParentOptionals(taskPath, result); 1050 taskPath.removeLast(); 1051 } 1052 } 1053 else if (task instanceof IIteration) { 1054 taskPath.add(((IIteration) task).getMarkedTask(), 0); 1055 getParentOptionals(taskPath, result); 1056 taskPath.removeLast(); 1126 private void getUnexecutedParentOptionals(ITask task, 1127 List<TaskPath> result) 1128 { 1129 for (ITaskInstance instance : task.getInstances()) { 1130 TaskPath taskPath = new TaskPath(); 1131 taskPath.add(task, 0); 1132 getUnexecutedParentOptionals(instance, taskPath, result); 1133 } 1134 } 1135 1136 /** 1137 * 1138 */ 1139 private void getUnexecutedParentOptionals(ITaskInstance instance, 1140 TaskPath currentPath, 1141 List<TaskPath> result) 1142 { 1143 if (instance instanceof IOptionalInstance) { 1144 ITaskInstance child = ((IOptionalInstance) instance).getChild(); 1145 if (child != null) { 1146 currentPath.add(child.getTask(), 0); 1147 getUnexecutedParentOptionals(child, currentPath, result); 1148 currentPath.removeLast(); 1149 } 1150 else { 1151 result.add(currentPath.subPath(0, currentPath.size())); // ensure to create a copy 1152 } 1153 } 1154 else if (instance instanceof IIterationInstance) { 1155 currentPath.add(((IIteration) instance.getTask()).getMarkedTask(), 0); 1156 1157 for (ITaskInstance child : (IIterationInstance) instance) { 1158 getUnexecutedParentOptionals(child, currentPath, result); 1159 } 1160 1161 currentPath.removeLast(); 1162 } 1163 else if (instance instanceof ISequenceInstance) { 1164 int index = 0; 1165 for (ITaskInstance child : (ISequenceInstance) instance) { 1166 currentPath.add(child.getTask(), index++); 1167 getUnexecutedParentOptionals(child, currentPath, result); 1168 currentPath.removeLast(); 1169 } 1170 } 1171 else if (instance instanceof ISelectionInstance) { 1172 ITaskInstance child = ((ISelectionInstance) instance).getChild(); 1173 currentPath.add(child.getTask(), 0); 1174 getUnexecutedParentOptionals(child, currentPath, result); 1175 currentPath.removeLast(); 1057 1176 } 1058 1177 }
Note: See TracChangeset
for help on using the changeset viewer.