Changeset 1982


Ignore:
Timestamp:
06/30/15 10:26:24 (9 years ago)
Author:
pharms
Message:
  • no merging if mergable level of similarity is 100 --> a selection of both tasks to be merged would be created
  • reuse of intermediary tasks also for merge results if identical
  • selections having themselves as direct of indirect child will not be created --> merging aborted
  • harmonizations of marking temporal relationships for merged sequences
  • integration of single iterations if a merged sequence is iterated somewhere
  • detection of repetitions of identical tasks that became identical due to merging
  • removal or sequences that have only one child
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/CondenseSimilarTasksRule.java

    r1976 r1982  
    2828import de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTraversal; 
    2929import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     30import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    3031import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 
    3132import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 
     
    4546import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
    4647import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskPath; 
     48import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskTreeUtils; 
    4749import de.ugoe.cs.util.console.Console; 
    4850import difflib.Chunk; 
     
    194196             
    195197            /*mergecount++; 
    196             if ((mergecount > 140) && ((mergecount % 20) == 0)) { 
     198            System.out.println(mergecount); 
     199            if ((mergecount % 20) == 0) { 
    197200                System.out.println("performing validation " + mergecount); 
    198                 new TaskTreeValidator().validate(appData.getTaskModel().getUserSessions(), true); 
     201                new de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTreeValidator() 
     202                    .validate(appData.getTaskModel().getUserSessions(), true); 
    199203            }*/ 
    200              
    201204             
    202205            appData.setMostSimilarTasks(null); 
     
    235238            } 
    236239             
    237             harmonizeMarkingTemporalRelationships(sessions); 
     240            harmonizeModel(sessions, appData.getTaskModel()); 
    238241        } 
    239242        while (appData.getMostSimilarTasks() != null); 
     
    284287     * 
    285288     */ 
    286     private void harmonizeMarkingTemporalRelationships(List<IUserSession> sessions) { 
    287         final Map<ITask, IIteration> harmonizedIterations = new HashMap<>(); 
    288         final Map<ITask, IOptional> harmonizedOptionals = new HashMap<>(); 
    289          
    290         for (IUserSession session : sessions) { 
    291             for (ITaskInstance instance : session) { 
    292                 instance.accept(new DefaultTaskInstanceTraversingVisitor() { 
    293                      
    294                     @Override 
    295                     public void visit(IIterationInstance iterationInstance) { 
    296                         // visit the children 
    297                         super.visit(iterationInstance); 
    298                          
    299                         // there may have been a model update at the children. If so, set the 
    300                         // new marked task 
    301                         IIteration iteration = iterationInstance.getIteration(); 
    302                         ITask newChildTask = iterationInstance.get(0).getTask(); 
    303                          
    304                         if (newChildTask != iteration.getMarkedTask()) { 
    305                             taskBuilder.setMarkedTask(iteration, newChildTask); 
    306                         } 
    307                          
    308                         // check, if there is a harmonized iteration 
    309                         IIteration harmonizedIteration = 
    310                             harmonizedIterations.get(iteration.getMarkedTask()); 
    311                          
    312                         if ((harmonizedIteration != null) && (iteration != harmonizedIteration)) { 
    313                             // there is a harmonized iteration --> set it as new task 
    314                             /*System.out.println("harmonizing iteration of " + 
    315                                                iteration.getMarkedTask() + " from " + iteration + 
    316                                                " to " + harmonizedIteration);*/ 
    317                             taskBuilder.setTask(iterationInstance, harmonizedIteration); 
    318                         } 
    319                         else if (harmonizedIteration == null) { 
    320                             // remember this iteration as the harmonized one 
    321                             harmonizedIterations.put(iteration.getMarkedTask(), iteration); 
    322                         } 
    323                     } 
    324                      
    325                     @Override 
    326                     public void visit(IOptionalInstance optionalInstance) { 
    327                         // visit the children 
    328                         super.visit(optionalInstance); 
    329                          
    330                         IOptional optional = optionalInstance.getOptional(); 
    331  
    332                         if (optionalInstance.getChild() != null) { 
    333                             // there may have been a model update at the child. If so, set the 
    334                             // new marked task 
    335                             ITask newChildTask = optionalInstance.getChild().getTask(); 
    336  
    337                             if (newChildTask != optional.getMarkedTask()) { 
    338                                 taskBuilder.setMarkedTask(optional, newChildTask); 
    339                             } 
    340                         } 
    341  
    342                         // check, if there is a harmonized optional 
    343                         IOptional harmonizedOptional = 
    344                             harmonizedOptionals.get(optional.getMarkedTask()); 
    345  
    346                         if ((harmonizedOptional != null) && (optional != harmonizedOptional)) { 
    347                             // there is a harmonized optional --> set it as new task 
    348                             /*System.out.println("harmonizing optional of " + 
    349                                                optional.getMarkedTask() + " from " + optional + 
    350                                                " to " + harmonizedOptional);*/ 
    351                             taskBuilder.setTask(optionalInstance, harmonizedOptional); 
    352                         } 
    353                         else if (harmonizedOptional == null) { 
    354                             // remember this optional as the harmonized one 
    355                             harmonizedOptionals.put(optional.getMarkedTask(), optional); 
    356                         } 
    357                     } 
    358  
    359                     @Override 
    360                     public void visit(ISelectionInstance selectionInstance) { 
    361                         ITask childTaskBeforeUpdate = selectionInstance.getChild().getTask(); 
    362                          
    363                         super.visit(selectionInstance); 
    364                          
    365                         ITask childTaskAfterUpdate = selectionInstance.getChild().getTask(); 
    366                          
    367                         if (childTaskBeforeUpdate != childTaskAfterUpdate) { 
    368                             // update the selection model if required. 
    369                             ISelection selection = selectionInstance.getSelection(); 
    370                              
    371                             boolean foundOtherInstanceWithOldChild = false; 
    372                              
    373                             for (ITaskInstance instance : selection.getInstances()) { 
    374                                 ITask child = ((ISelectionInstance) instance).getChild().getTask(); 
    375                                  
    376                                 if (child == childTaskBeforeUpdate) { 
    377                                     foundOtherInstanceWithOldChild = true; 
    378                                     break; 
    379                                 } 
    380                             } 
    381                              
    382                             if (!foundOtherInstanceWithOldChild) { 
    383                                 taskBuilder.removeChild(selection, childTaskBeforeUpdate); 
    384                             } 
    385                              
    386                             // remove and add the child to ensure to have it only once 
    387                             taskBuilder.removeChild(selection, childTaskAfterUpdate); 
    388                             taskBuilder.addChild(selection, childTaskAfterUpdate); 
    389                         } 
    390                     } 
    391  
    392                     @Override 
    393                     public void visit(ISequenceInstance sequenceInstance) { 
    394                         ISequence sequence = sequenceInstance.getSequence(); 
    395                         int childIndex = 0; 
    396                          
    397                         for (ITaskInstance child : sequenceInstance) { 
    398                             child.accept(this); 
    399                              
    400                             ITask newChildTask = child.getTask(); 
    401                              
    402                             if (sequence.getChildren().get(childIndex) != newChildTask) { 
    403                                 taskBuilder.setChild(sequenceInstance.getSequence(), childIndex, 
    404                                                      newChildTask); 
    405                             } 
    406                              
    407                             childIndex++; 
    408                         } 
    409                     } 
    410                      
    411                 }); 
    412  
    413             } 
    414              
    415             // several subsequent instances, which had formerly different tasks, may now have 
    416             // the same. Hence, they need to be merged. But as everything else would be way too 
    417             // complex, we only perform the merge, if they occur next to each other on the 
    418             // same level 
    419             mergeSubsequentIdenticalMarkingTemporalRelationships(session); 
    420         } 
     289    private void harmonizeModel(List<IUserSession> sessions, ITaskModel model) { 
     290        boolean somethingChanged; 
     291         
     292        do { 
     293            // harmonize marking temporal relationships 
     294            MarkingTemporalRelationshipHarmonizer harmonizer = 
     295                new MarkingTemporalRelationshipHarmonizer(); 
     296         
     297            for (IUserSession session : sessions) { 
     298                for (ITaskInstance instance : session) { 
     299                    instance.accept(harmonizer); 
     300                } 
     301            } 
     302             
     303            // integrate iterations performed once for children that were somewhere iterated more 
     304            // than once 
     305            SingleIterationExecutionsIntegrator integrator = 
     306                new SingleIterationExecutionsIntegrator(harmonizer.harmonizedIterations); 
     307 
     308            for (IUserSession session : sessions) { 
     309                for (ITaskInstance instance : session) { 
     310                    instance.accept(integrator); 
     311                } 
     312            } 
     313             
     314            // search for sequences having subsequent identical children (may be the result 
     315            // of merging two subsequent children) 
     316            SubsequentIdenticalChildrenMerger merger = new SubsequentIdenticalChildrenMerger(); 
     317            for (ITask task : model.getTasks()) { 
     318                merger.mergeSubsequentIdenticalTasks(task); 
     319            } 
     320             
     321            for (IUserSession session : sessions) { 
     322                merger.mergeSubsequentIdenticalInstances(session); 
     323            } 
     324             
     325            somethingChanged = harmonizer.somethingChanged || integrator.somethingChanged || 
     326                merger.somethingChanged; 
     327                     
     328        } 
     329        while(somethingChanged); 
    421330    } 
    422331 
     
    477386            (similarTasks, identTaskHandlStrat.getTaskComparator()); 
    478387         
    479         if (similarTasks == null) { 
     388        if ((similarTasks == null) || (similarTasks.getDiffLevel() == 100)) { 
    480389            // this may happen, if no mergable level of similarity can be found 
    481390            return; 
     
    486395        List<FlattenInstruction> flattenInstructions = 
    487396            getFlattenInstructions(similarTasks, appData); 
     397         
     398        if (flattenInstructions == null) { 
     399            // we cannot merge this 
     400            return; 
     401        } 
    488402         
    489403        // for (FlattenInstruction instruction : flattenInstructions) { 
     
    572486        } 
    573487         
    574         /*if (replacements.size() > 0) { 
     488        /*if (replacementTask != null) { 
    575489            System.out.println("replacement task is calculated to be: "); 
    576             new TaskTreeEncoder().encode(replacements.values().iterator().next().getTask(), 
    577                                         System.out); 
     490            new de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils.TaskTreeEncoder().encode 
     491                (replacementTask, System.out); 
    578492        }*/ 
    579493         
     
    581495        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    582496 
     497        ITask uniqueReplacement = appData.ensureUnique(replacementTask); 
     498         
     499        if (uniqueReplacement != replacementTask) { 
     500            System.out.println("updating task instances with a unified replacement task"); 
     501            for (ITaskInstance replacement : replacements.values()) { 
     502                taskBuilder.setTask(replacement, uniqueReplacement); 
     503            } 
     504        } 
    583505 
    584506        for (IUserSession session : appData.getSessions()) { 
     
    760682                                else if (selection.getChildren().contains(child2)) { 
    761683                                    existingChildTask = child2; 
    762                                } 
     684                                } 
    763685                                 
    764686                                if (existingChildTask != null) { 
     
    812734                        } 
    813735                    } 
    814  
     736                     
     737                    // tasks that refer to themselves are not valid. But due to the creation of 
     738                    // selections, this may happen. This must be prevented 
     739                    /*final Set<ITask> tasks = new HashSet<ITask>(); 
     740                     
     741                    try { 
     742                        selection.accept(new DefaultTaskTraversingVisitor() { 
     743                            @Override 
     744                            public void visit(ITask task) { 
     745                                if (!tasks.contains(task)) { 
     746                                    tasks.add(task); 
     747                                    super.visit(task); 
     748                                } 
     749                                else { 
     750                                    throw new RuntimeException("tasks refers to itself"); 
     751                                } 
     752                            } 
     753                        }); 
     754                    } 
     755                    catch (RuntimeException e) { 
     756                        // a task refers to itself 
     757                        return null; 
     758                    }*/ 
     759                     
     760                    // the new selection does not refer to itself, no apply it 
    815761                    selection = (ISelection) appData.ensureUnique(selection); 
    816                  
     762                     
    817763                    createReplacementInstructions 
    818764                        (delta.getOriginal(), selection, expectedChild1, result); 
     
    907853     */ 
    908854    private void addSelectionChildIfRequired(ISelection selection, ITask child) { 
     855        if (TaskTreeUtils.isChild(selection, child)) { 
     856            System.out.println(selection); 
     857            System.out.println(child); 
     858            throw new RuntimeException("child of selection has selection itself as child"); 
     859        } 
    909860        for (ITask candidate : selection.getChildren()) { 
    910861            if (identTaskHandlStrat.getTaskComparator().equals(candidate, child)) { 
     
    10981049                            // first check, if the instance was already created, if not create it 
    10991050                            ISequenceInstance sequenceInstance = ensureSequenceChildInstanceFor 
    1100                                 (selection, (ISequence) instruction.getSelectedChild(),  session); 
     1051                                (selection, (ISequence) instruction.getSelectedChild(), session); 
    11011052 
    11021053                            taskBuilder.addChild(sequenceInstance, instance); 
     
    14691420        } 
    14701421    } 
    1471      
    1472     /** 
    1473      * 
    1474      */ 
    1475     private void mergeSubsequentIdenticalMarkingTemporalRelationships(ITaskInstanceList list) { 
    1476         int index = 0; 
    1477         TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 
    1478          
    1479         while (index < (list.size() - 1)) { 
    1480             ITaskInstance instance1 = list.get(index); 
    1481             ITaskInstance instance2 = list.get(index + 1); 
    1482              
    1483             if (comparator.equals(instance1.getTask(), instance2.getTask())) { 
    1484                 if (instance1 instanceof IIterationInstance) { 
    1485                     // add the children of the second to the first iteration instance and discard 
    1486                     // the second 
    1487                     for (ITaskInstance child : (IIterationInstance) instance2) { 
    1488                         taskBuilder.addChild((IIterationInstance) instance1, child);  
    1489                     } 
    1490                      
    1491                     taskBuilder.removeTaskInstance(list, index + 1); 
    1492                     taskBuilder.discardTaskInstance(instance2); 
    1493                 } 
    1494                 else if (instance1 instanceof IOptionalInstance) { 
    1495                     ITaskInstance optionalChildInstance1 = 
    1496                         ((IOptionalInstance) instance1).getChild(); 
    1497                     ITaskInstance optionalChildInstance2 = 
    1498                             ((IOptionalInstance) instance2).getChild(); 
    1499                          
    1500                     if (optionalChildInstance1 == null) { 
    1501                         // independent of the second, just remove the first. The second will be the 
    1502                         // unique representation 
    1503                         taskBuilder.removeTaskInstance(list, index); 
    1504                     } 
    1505                     else if (optionalChildInstance2 == null) { 
    1506                         // remove the second. The first will be the unique representation 
    1507                         taskBuilder.removeTaskInstance(list, index + 1); 
    1508                     } 
    1509                     else if (optionalChildInstance1 instanceof IIterationInstance) { 
    1510                         // add all children of the second optional iteration instance to the 
    1511                         // first and discard the second 
    1512                         for (ITaskInstance child : (IIterationInstance) optionalChildInstance2) { 
    1513                             taskBuilder.addChild 
    1514                                 ((IIterationInstance) optionalChildInstance1, child);  
    1515                         } 
    1516                          
    1517                         taskBuilder.removeTaskInstance(list, index + 1); 
    1518                         taskBuilder.discardTaskInstance(instance2); 
    1519                     } 
    1520                     else { 
    1521                         // both optional children are no iterations --> create an iteration 
    1522                         // for them and add them both as children. 
    1523                         throw new java.lang.UnsupportedOperationException("not implemented yet"); 
    1524                     } 
    1525                 } 
    1526                 else { 
    1527                     index++; 
    1528                 } 
    1529             } 
    1530             else { 
    1531                 index++; 
    1532             } 
    1533         } 
    1534          
    1535         for (ITaskInstance child : list) { 
    1536             if (child instanceof ITaskInstanceList) { 
    1537                 mergeSubsequentIdenticalMarkingTemporalRelationships((ITaskInstanceList) child); 
    1538             } 
    1539         } 
    1540     } 
    1541      
     1422 
    15421423    /** 
    15431424     * 
     
    15591440        } 
    15601441    } 
    1561  
    1562     /** 
    1563      * 
    1564      */ 
    1565     /*private boolean containsNewTask(ITask task, RuleApplicationData appData) { 
    1566         if (appData.isSelfCreatedTask(task)) { 
    1567             return true; 
    1568         } 
    1569         else if (task instanceof IStructuringTemporalRelationship) { 
    1570             for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 
    1571                 if (containsNewTask(child, appData)) { 
    1572                     return true; 
    1573                 } 
    1574             } 
    1575         } 
    1576         else if (task instanceof IMarkingTemporalRelationship) { 
    1577             return containsNewTask(((IMarkingTemporalRelationship) task).getMarkedTask(), appData); 
    1578         } 
    1579          
    1580         return false; 
    1581     }*/ 
     1442     
     1443    /** 
     1444     *  
     1445     */ 
     1446    private void removeSelectionChildIfNotUsedAnymoreInInstances(ISelection selection, ITask child) { 
     1447        boolean foundOtherInstanceWithChild = false; 
     1448         
     1449        for (ITaskInstance instance : selection.getInstances()) { 
     1450            ITask candidate = ((ISelectionInstance) instance).getChild().getTask(); 
     1451             
     1452            if (candidate == child) { 
     1453                foundOtherInstanceWithChild = true; 
     1454                break; 
     1455            } 
     1456        } 
     1457         
     1458        if (!foundOtherInstanceWithChild) { 
     1459            taskBuilder.removeChild(selection, child); 
     1460        } 
     1461 
     1462    } 
    15821463 
    15831464    /** 
     
    19831864    } 
    19841865 
     1866    /** 
     1867     *  
     1868     */ 
     1869    private class MarkingTemporalRelationshipHarmonizer 
     1870        extends DefaultTaskInstanceTraversingVisitor 
     1871    { 
     1872        /** */ 
     1873        final Map<ITask, IIteration> harmonizedIterations = new HashMap<>(); 
     1874         
     1875        /** */ 
     1876        final Map<ITask, IOptional> harmonizedOptionals = new HashMap<>(); 
     1877         
     1878        /** */ 
     1879        private boolean somethingChanged = false; 
     1880         
     1881        /** 
     1882         *  
     1883         */ 
     1884        @Override 
     1885        public void visit(IIterationInstance iterationInstance) { 
     1886            // visit the children 
     1887            super.visit(iterationInstance); 
     1888             
     1889            // there may have been a model update at the children. If so, set the 
     1890            // new marked task 
     1891            IIteration iteration = iterationInstance.getIteration(); 
     1892            ITask newChildTask = iterationInstance.get(0).getTask(); 
     1893             
     1894            if (newChildTask != iteration.getMarkedTask()) { 
     1895                taskBuilder.setMarkedTask(iteration, newChildTask); 
     1896            } 
     1897             
     1898            // check, if there is a harmonized iteration 
     1899            IIteration harmonizedIteration = 
     1900                harmonizedIterations.get(iteration.getMarkedTask()); 
     1901             
     1902            if ((harmonizedIteration != null) && (iteration != harmonizedIteration)) { 
     1903                // there is a harmonized iteration --> set it as new task 
     1904                /*System.out.println("harmonizing iteration of " + 
     1905                                   iteration.getMarkedTask() + " from " + iteration + 
     1906                                   " to " + harmonizedIteration);*/ 
     1907                taskBuilder.setTask(iterationInstance, harmonizedIteration); 
     1908                somethingChanged = true; 
     1909            } 
     1910            else if (harmonizedIteration == null) { 
     1911                // remember this iteration as the harmonized one 
     1912                harmonizedIterations.put(iteration.getMarkedTask(), iteration); 
     1913            } 
     1914        } 
     1915         
     1916        /** 
     1917         *  
     1918         */ 
     1919        @Override 
     1920        public void visit(IOptionalInstance optionalInstance) { 
     1921            // visit the children 
     1922            super.visit(optionalInstance); 
     1923             
     1924            IOptional optional = optionalInstance.getOptional(); 
     1925 
     1926            if (optionalInstance.getChild() != null) { 
     1927                // there may have been a model update at the child. If so, set the 
     1928                // new marked task 
     1929                ITask newChildTask = optionalInstance.getChild().getTask(); 
     1930                 
     1931                if (newChildTask != optional.getMarkedTask()) { 
     1932                    taskBuilder.setMarkedTask(optional, newChildTask); 
     1933                } 
     1934            } 
     1935 
     1936            // check, if there is a harmonized optional 
     1937            IOptional harmonizedOptional = 
     1938                harmonizedOptionals.get(optional.getMarkedTask()); 
     1939 
     1940            if ((harmonizedOptional != null) && (optional != harmonizedOptional)) { 
     1941                // there is a harmonized optional --> set it as new task 
     1942                /*System.out.println("harmonizing optional of " + 
     1943                                   optional.getMarkedTask() + " from " + optional + 
     1944                                   " to " + harmonizedOptional);*/ 
     1945                taskBuilder.setTask(optionalInstance, harmonizedOptional); 
     1946                somethingChanged = true; 
     1947            } 
     1948            else if (harmonizedOptional == null) { 
     1949                // remember this optional as the harmonized one 
     1950                harmonizedOptionals.put(optional.getMarkedTask(), optional); 
     1951            } 
     1952        } 
     1953 
     1954        /** 
     1955         *  
     1956         */ 
     1957        @Override 
     1958        public void visit(ISelectionInstance selectionInstance) { 
     1959            ITask childTaskBeforeUpdate = selectionInstance.getChild().getTask(); 
     1960             
     1961            super.visit(selectionInstance); 
     1962             
     1963            ITask childTaskAfterUpdate = selectionInstance.getChild().getTask(); 
     1964             
     1965            if (childTaskBeforeUpdate != childTaskAfterUpdate) { 
     1966                // update the selection model if required. 
     1967                ISelection selection = selectionInstance.getSelection(); 
     1968                removeSelectionChildIfNotUsedAnymoreInInstances(selection, childTaskBeforeUpdate); 
     1969                 
     1970                // remove and add the child to ensure to have it only once 
     1971                taskBuilder.removeChild(selection, childTaskAfterUpdate); 
     1972                taskBuilder.addChild(selection, childTaskAfterUpdate); 
     1973                somethingChanged = true; 
     1974            } 
     1975        } 
     1976 
     1977        /** 
     1978         *  
     1979         */ 
     1980        @Override 
     1981        public void visit(ISequenceInstance sequenceInstance) { 
     1982            ISequence sequence = sequenceInstance.getSequence(); 
     1983            int childIndex = 0; 
     1984             
     1985            for (ITaskInstance child : sequenceInstance) { 
     1986                child.accept(this); 
     1987                 
     1988                ITask newChildTask = child.getTask(); 
     1989                 
     1990                if (sequence.getChildren().get(childIndex) != newChildTask) { 
     1991                    taskBuilder.setChild(sequenceInstance.getSequence(), childIndex, 
     1992                                         newChildTask); 
     1993                    somethingChanged = true; 
     1994                } 
     1995                 
     1996                childIndex++; 
     1997            } 
     1998        } 
     1999         
     2000    } 
     2001     
     2002 
     2003    /** 
     2004     *  
     2005     */ 
     2006    private class SingleIterationExecutionsIntegrator 
     2007        extends DefaultTaskInstanceTraversingVisitor 
     2008    { 
     2009 
     2010        /** */ 
     2011        private Map<ITask, IIteration> iterations; 
     2012         
     2013        /** */ 
     2014        private boolean somethingChanged = false; 
     2015 
     2016        /** 
     2017         * 
     2018         */ 
     2019        public SingleIterationExecutionsIntegrator(Map<ITask, IIteration> iterations) { 
     2020            this.iterations = iterations; 
     2021        } 
     2022 
     2023        /* (non-Javadoc) 
     2024         * @see DefaultTaskInstanceTraversingVisitor#visit(IOptionalInstance) 
     2025         */ 
     2026        @Override 
     2027        public void visit(IOptionalInstance optionalInstance) { 
     2028            super.visit(optionalInstance); 
     2029 
     2030            if (optionalInstance.getChild() != null) { 
     2031                IIteration iteration = iterations.get(optionalInstance.getChild().getTask()); 
     2032 
     2033                if (iteration != null) { 
     2034                    taskBuilder.setMarkedTask(optionalInstance.getOptional(), iteration); 
     2035                    IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 
     2036                    taskBuilder.addChild(replacement, optionalInstance.getChild()); 
     2037                    taskBuilder.setChild(optionalInstance, replacement); 
     2038                    somethingChanged = true; 
     2039                } 
     2040            } 
     2041        } 
     2042 
     2043        /* (non-Javadoc) 
     2044         * @see DefaultTaskInstanceTraversingVisitor#visit(ISelectionInstance) 
     2045         */ 
     2046        @Override 
     2047        public void visit(ISelectionInstance selectionInstance) { 
     2048            super.visit(selectionInstance); 
     2049             
     2050            ITask usedChildTask = selectionInstance.getChild().getTask(); 
     2051            IIteration iteration = iterations.get(usedChildTask); 
     2052             
     2053            if (iteration != null) { 
     2054                // extend the selection model 
     2055                // remove and add the child to ensure to have it only once 
     2056                ISelection selection = selectionInstance.getSelection(); 
     2057                taskBuilder.removeChild(selection, iteration); 
     2058                taskBuilder.addChild(selection, iteration); 
     2059                 
     2060                // update the instance 
     2061                IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 
     2062                taskBuilder.addChild(replacement, selectionInstance.getChild()); 
     2063                taskBuilder.setChild(selectionInstance, replacement); 
     2064                 
     2065                // update the selection model if required. 
     2066                removeSelectionChildIfNotUsedAnymoreInInstances(selection, usedChildTask); 
     2067                 
     2068                somethingChanged = true; 
     2069            } 
     2070 
     2071        } 
     2072 
     2073        /* (non-Javadoc) 
     2074         * @see DefaultTaskInstanceTraversingVisitor#visit(ISequenceInstance) 
     2075         */ 
     2076        @Override 
     2077        public void visit(ISequenceInstance sequenceInstance) { 
     2078            int index = 0; 
     2079            while (index < sequenceInstance.size()) { 
     2080                ITaskInstance child = sequenceInstance.get(index); 
     2081                child.accept(this); 
     2082                 
     2083                IIteration iteration = iterations.get(child.getTask()); 
     2084                 
     2085                if (iteration != null) { 
     2086                    taskBuilder.setChild(sequenceInstance.getSequence(), index, iteration); 
     2087                    IIterationInstance replacement = taskFactory.createNewTaskInstance(iteration); 
     2088                    taskBuilder.addChild(replacement, child); 
     2089                    taskBuilder.setTaskInstance(sequenceInstance, index, replacement); 
     2090                    somethingChanged = true; 
     2091                } 
     2092                 
     2093                index++; 
     2094            } 
     2095        } 
     2096 
     2097    } 
     2098 
     2099    /** 
     2100     *  
     2101     */ 
     2102    private class SubsequentIdenticalChildrenMerger { 
     2103         
     2104        /** */ 
     2105        private boolean somethingChanged = false; 
     2106 
     2107        /** 
     2108         * 
     2109         */ 
     2110        private void mergeSubsequentIdenticalTasks(ITask task) { 
     2111            TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 
     2112 
     2113            if (task instanceof ISequence) { 
     2114                // merge the children 
     2115                mergeSubsequentIdenticalTasks((ISequence) task); 
     2116                 
     2117                int index = 0; 
     2118                 
     2119                while (index < ((ISequence) task).getChildren().size()) { 
     2120                    ITask child = ((ISequence) task).getChildren().get(index); 
     2121 
     2122                    List<ITaskInstance> childInstances = new LinkedList<>(); 
     2123                     
     2124                    for (ITaskInstance instance : task.getInstances()) { 
     2125                        ITaskInstance childInstance = ((ISequenceInstance) instance).get(index); 
     2126                        if (comparator.equals(childInstance.getTask(), child)) { 
     2127                            childInstances.add(childInstance); 
     2128                        } 
     2129                    } 
     2130                     
     2131                    Map<ITaskInstance, ITaskInstance> childInstanceReplacements = new HashMap<>(); 
     2132                     
     2133                    ITask replacementTask = 
     2134                        getReplacements(child, childInstances, childInstanceReplacements); 
     2135                         
     2136                    if (replacementTask != null) { 
     2137                        taskBuilder.setChild((ISequence) task, index, replacementTask); 
     2138 
     2139                        for (ITaskInstance instance : task.getInstances()) { 
     2140                            ITaskInstance childInstance = ((ISequenceInstance) instance).get(index); 
     2141                            ITaskInstance replacement = childInstanceReplacements.get(childInstance); 
     2142 
     2143                            if (replacement != null) { 
     2144                                taskBuilder.setTaskInstance 
     2145                                    ((ISequenceInstance) instance, index, replacement); 
     2146                            } 
     2147                        } 
     2148                         
     2149                        somethingChanged = true; 
     2150                    } 
     2151                     
     2152                    index++; 
     2153                } 
     2154            } 
     2155            else if (task instanceof ISelection) { 
     2156                // it could have children being marking temporal relationship of a sequence of 
     2157                // interest. If so, adapt the model and the instances 
     2158                int index = 0; 
     2159                 
     2160                while (index < ((ISelection) task).getChildren().size()) { 
     2161                    ITask child = ((ISelection) task).getChildren().get(index); 
     2162                    List<ITaskInstance> childInstances = new LinkedList<>(); 
     2163                     
     2164                    for (ITaskInstance instance : task.getInstances()) { 
     2165                        ITaskInstance childInstance = ((ISelectionInstance) instance).getChild(); 
     2166                        if (comparator.equals(childInstance.getTask(), child)) { 
     2167                            childInstances.add(childInstance); 
     2168                        } 
     2169                    } 
     2170                     
     2171                    Map<ITaskInstance, ITaskInstance> childInstanceReplacements = new HashMap<>(); 
     2172                     
     2173                    ITask replacementTask = 
     2174                        getReplacements(child, childInstances, childInstanceReplacements); 
     2175                     
     2176                    if (replacementTask != null) { 
     2177                        taskBuilder.removeChild((ISelection) task, child); 
     2178                        taskBuilder.addChild((ISelection) task, replacementTask); 
     2179 
     2180                        for (ITaskInstance instance : task.getInstances()) { 
     2181                            ITaskInstance childInstance = ((ISelectionInstance) instance).getChild(); 
     2182                            ITaskInstance replacement = childInstanceReplacements.get(childInstance); 
     2183 
     2184                            if (replacement != null) { 
     2185                                taskBuilder.setChild(((ISelectionInstance) instance), replacement); 
     2186                            } 
     2187                        } 
     2188                         
     2189                        // start from the beginning as the children order may have changed 
     2190                        index = 0; 
     2191                        somethingChanged = true; 
     2192                    } 
     2193                    else { 
     2194                        index++; 
     2195                    } 
     2196                } 
     2197            } 
     2198        } 
     2199 
     2200        /** 
     2201         * 
     2202         */ 
     2203        private ITask getReplacements(ITask                             child, 
     2204                                      List<ITaskInstance>               childInstances, 
     2205                                      Map<ITaskInstance, ITaskInstance> childInstanceReplacements) 
     2206        { 
     2207            final TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 
     2208            ITask candidate = child; 
     2209            boolean isOptional = false; 
     2210             
     2211            while (candidate instanceof IMarkingTemporalRelationship) { 
     2212                if (candidate instanceof IOptional) { 
     2213                    isOptional = true; 
     2214                } 
     2215                candidate = ((IMarkingTemporalRelationship) candidate).getMarkedTask(); 
     2216            } 
     2217             
     2218            if ((candidate instanceof IEventTask) || (candidate instanceof ISelection) || 
     2219                (((ISequence) candidate).getChildren().size() != 1)) 
     2220            { 
     2221                // no sequence of interest as it has more than one children 
     2222                return null; 
     2223            } 
     2224             
     2225            // found a sequence to be handled. The sequence has a single child and this will 
     2226            // be either an optional of an iteration of the single child, or an iteration of 
     2227            // the single child. 
     2228            final ISequence sequenceWithSingleChild = (ISequence) candidate; 
     2229             
     2230            // determine all instances of the sequence rooted by the provided parent instance 
     2231            ITask singleChild = sequenceWithSingleChild.getChildren().get(0); 
     2232            IOptional optional = null; 
     2233 
     2234            if (singleChild instanceof IOptional) { 
     2235                isOptional = true; 
     2236                optional = (IOptional) singleChild; 
     2237                singleChild = optional.getMarkedTask(); 
     2238            } 
     2239 
     2240            IIteration iteration = (IIteration) singleChild; 
     2241 
     2242            if (isOptional && (optional == null)) { 
     2243                optional = taskFactory.createNewOptional(); 
     2244                taskBuilder.setMarkedTask(optional, iteration); 
     2245            } 
     2246 
     2247            for (ITaskInstance childInstance : childInstances) { 
     2248                // get all instances of the single child of the sequence of interest which belong to 
     2249                // the a child instance to be replaced and calculate a replacement 
     2250                final List<ITaskInstance> singleChildInstances = new LinkedList<>(); 
     2251                final ITask taskToSearchFor = singleChild; 
     2252                 
     2253                childInstance.accept(new DefaultTaskInstanceTraversingVisitor() { 
     2254                    @Override 
     2255                    public void visit(ISelectionInstance selectionInstance) { 
     2256                        if (comparator.equals(selectionInstance.getTask(), taskToSearchFor)) { 
     2257                            singleChildInstances.add(selectionInstance); 
     2258                        } 
     2259                    } 
     2260 
     2261                    @Override 
     2262                    public void visit(ISequenceInstance sequenceInstance) { 
     2263                        if (comparator.equals(sequenceInstance.getTask(), taskToSearchFor)) { 
     2264                            singleChildInstances.add(sequenceInstance); 
     2265                        } 
     2266                        else if (comparator.equals(sequenceInstance.getTask(), 
     2267                                                   sequenceWithSingleChild)) 
     2268                        { 
     2269                            super.visit(sequenceInstance); 
     2270                        } 
     2271                    } 
     2272                     
     2273                }); 
     2274                 
     2275                IIterationInstance iterationInstance = taskFactory.createNewTaskInstance(iteration); 
     2276                for (ITaskInstance singleChildInstance : singleChildInstances) { 
     2277                    taskBuilder.addTaskInstance(iterationInstance, singleChildInstance); 
     2278                } 
     2279                 
     2280                ITaskInstance replacement = iterationInstance; 
     2281                 
     2282                if (isOptional) { 
     2283                    IOptionalInstance optionalInstance = taskFactory.createNewTaskInstance(optional); 
     2284                    taskBuilder.setChild(optionalInstance, replacement); 
     2285                    replacement = optionalInstance; 
     2286                } 
     2287                 
     2288                childInstanceReplacements.put(childInstance, replacement); 
     2289            } 
     2290             
     2291            if (isOptional) { 
     2292                return optional; 
     2293            } 
     2294            else { 
     2295                return iteration; 
     2296            } 
     2297        } 
     2298 
     2299        /** 
     2300         * 
     2301         */ 
     2302        private void mergeSubsequentIdenticalTasks(ISequence sequence) { 
     2303            int index = 0; 
     2304            TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 
     2305             
     2306            while (index < (sequence.getChildren().size() - 1)) { 
     2307                ITask child1 = sequence.getChildren().get(index); 
     2308                ITask child2 = sequence.getChildren().get(index + 1); 
     2309                 
     2310                // get the actual first task 
     2311                ITask task1 = child1; 
     2312                 
     2313                while (task1 instanceof IMarkingTemporalRelationship) { 
     2314                    task1 = ((IMarkingTemporalRelationship) task1).getMarkedTask(); 
     2315                } 
     2316                 
     2317                // get the actual second task 
     2318                ITask task2 = child2; 
     2319                 
     2320                while (task2 instanceof IMarkingTemporalRelationship) { 
     2321                    task2 = ((IMarkingTemporalRelationship) task2).getMarkedTask(); 
     2322                } 
     2323                 
     2324                if (comparator.equals(task1, task2)) { 
     2325                    // determine if the task is optional 
     2326                    boolean isOptional = false; 
     2327                     
     2328                    if (child1 instanceof IOptional) { 
     2329                        child1 = ((IOptional) child1).getMarkedTask(); 
     2330                        isOptional = true; 
     2331                    } 
     2332                     
     2333                    if (child2 instanceof IOptional) { 
     2334                        child2 = ((IOptional) child2).getMarkedTask(); 
     2335                        isOptional = true; 
     2336                    } 
     2337                     
     2338                    if (child1 instanceof IIteration) { 
     2339                        child1 = ((IIteration) child1).getMarkedTask(); 
     2340                    } 
     2341                     
     2342                    if (child2 instanceof IIteration) { 
     2343                        child2 = ((IIteration) child2).getMarkedTask(); 
     2344                    } 
     2345                     
     2346                    IIteration iteration = taskFactory.createNewIteration(); 
     2347                    taskBuilder.setMarkedTask(iteration, task1); 
     2348                     
     2349                    IOptional optional = null; 
     2350                     
     2351                    if (isOptional) { 
     2352                        optional = taskFactory.createNewOptional(); 
     2353                        taskBuilder.setMarkedTask(optional, iteration); 
     2354                        taskBuilder.setChild(sequence, index, optional); 
     2355                    } 
     2356                    else { 
     2357                        taskBuilder.setChild(sequence, index, iteration); 
     2358                    } 
     2359                     
     2360                    taskBuilder.removeChild(sequence, index + 1); 
     2361                     
     2362                    for (ITaskInstance instance : sequence.getInstances()) { 
     2363                        mergeSubsequentIdenticalInstances((ISequenceInstance) instance, index, 
     2364                                                          iteration, optional); 
     2365                    } 
     2366                     
     2367                    somethingChanged = true; 
     2368                } 
     2369                else { 
     2370                    index++; 
     2371                } 
     2372            } 
     2373        } 
     2374 
     2375        /** 
     2376         * 
     2377         */ 
     2378        private void mergeSubsequentIdenticalInstances(ITaskInstanceList list) { 
     2379            int index = 0; 
     2380            TaskComparator comparator = identTaskHandlStrat.getTaskComparator(); 
     2381             
     2382            while (index < (list.size() - 1)) { 
     2383                boolean isOptional = false; 
     2384                ITaskInstance instance1 = list.get(index); 
     2385                ITaskInstance instance2 = list.get(index + 1); 
     2386                 
     2387                // get the actual first task 
     2388                ITask task1 = instance1.getTask(); 
     2389                 
     2390                while (task1 instanceof IMarkingTemporalRelationship) { 
     2391                    if (task1 instanceof IOptional) { 
     2392                        isOptional = true; 
     2393                    } 
     2394                     
     2395                    task1 = ((IMarkingTemporalRelationship) task1).getMarkedTask(); 
     2396                } 
     2397                 
     2398                // get the actual second task 
     2399                ITask task2 = instance2.getTask(); 
     2400                 
     2401                while (task2 instanceof IMarkingTemporalRelationship) { 
     2402                    if (task2 instanceof IOptional) { 
     2403                        isOptional = true; 
     2404                    } 
     2405                     
     2406                    task2 = ((IMarkingTemporalRelationship) task2).getMarkedTask(); 
     2407                } 
     2408                 
     2409                if (comparator.equals(task1, task2)) { 
     2410                    IIteration iteration = taskFactory.createNewIteration(); 
     2411                    IOptional optional = null; 
     2412                     
     2413                    if (isOptional) { 
     2414                        optional = taskFactory.createNewOptional(); 
     2415                        taskBuilder.setMarkedTask(optional, iteration); 
     2416                    } 
     2417                     
     2418                    mergeSubsequentIdenticalInstances(list, index, iteration, optional); 
     2419                } 
     2420                 
     2421                index++; 
     2422            } 
     2423        } 
     2424         
     2425        /** 
     2426         * 
     2427         */ 
     2428        private void mergeSubsequentIdenticalInstances(ITaskInstanceList list, 
     2429                                                       int               index, 
     2430                                                       IIteration        iteration, 
     2431                                                       IOptional         optional) 
     2432        { 
     2433            ITaskInstance instance1 = list.get(index); 
     2434            ITaskInstance instance2 = list.get(index + 1); 
     2435            List<ITaskInstance> equalInstances = new LinkedList<>(); 
     2436             
     2437            if (instance1 instanceof IOptionalInstance) { 
     2438                taskBuilder.discardTaskInstance(instance1); 
     2439                instance1 = ((IOptionalInstance) instance1).getChild(); 
     2440            } 
     2441             
     2442            if (instance2 instanceof IOptionalInstance) { 
     2443                taskBuilder.discardTaskInstance(instance2); 
     2444                instance2 = ((IOptionalInstance) instance2).getChild(); 
     2445            } 
     2446             
     2447            if (instance1 instanceof IIterationInstance) { 
     2448                for (ITaskInstance child : (IIterationInstance) instance1) { 
     2449                    equalInstances.add(child); 
     2450                } 
     2451                 
     2452                taskBuilder.discardTaskInstance(instance1); 
     2453            } 
     2454            else if (instance1 != null) { 
     2455                equalInstances.add(instance1); 
     2456            } 
     2457             
     2458            if (instance2 instanceof IIterationInstance) { 
     2459                for (ITaskInstance child : (IIterationInstance) instance2) { 
     2460                    equalInstances.add(child); 
     2461                } 
     2462                 
     2463                taskBuilder.discardTaskInstance(instance2); 
     2464            } 
     2465            else if (instance2 != null) { 
     2466                equalInstances.add(instance2); 
     2467            } 
     2468             
     2469            ITaskInstance replacement = taskFactory.createNewTaskInstance(iteration); 
     2470             
     2471            for (ITaskInstance equalInstance : equalInstances) { 
     2472                taskBuilder.addChild((IIterationInstance) replacement, equalInstance); 
     2473            } 
     2474             
     2475            if (optional != null) { 
     2476                IOptionalInstance optionalInstance = taskFactory.createNewTaskInstance(optional); 
     2477                 
     2478                taskBuilder.setChild(optionalInstance, replacement); 
     2479                replacement = optionalInstance; 
     2480            } 
     2481             
     2482            taskBuilder.setTaskInstance(list, index, replacement); 
     2483            taskBuilder.removeTaskInstance(list, index + 1); 
     2484        } 
     2485    } 
    19852486} 
Note: See TracChangeset for help on using the changeset viewer.