Ignore:
Timestamp:
04/04/13 16:06:07 (11 years ago)
Author:
pharms
Message:
  • complete refactoring of task tree model with a separation of task models and task instances
  • appropriate adaptation of task tree generation process
  • appropriate adaptation of commands and task tree visualization
Location:
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation
Files:
2 added
8 deleted
5 edited
1 moved

Legend:

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

    r1113 r1146  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
    17 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 
     17import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 
    1818 
    1919/** 
    2020 * <p> 
    21  * a temporal relationship rule is able to detected temporal relationships between the child nodes 
    22  * of the parent node provided to the {@link #apply(ITaskTreeNode, boolean)} method. A rule 
    23  * creates temporal relationships between the child nodes, i.e. substructures in the task tree, if 
    24  * it detects a temporal relationship and it can be sure that it is complete. Incomplete but 
    25  * detected temporal relationships may occur, if there can be more children expected to be added 
    26  * to the provided parent node. This could be the case during parsing a interaction log file of 
    27  * a GUI. 
     21 * a task instance list scope rule is able to detected temporal relationships between a list of task 
     22 * instances provided to the {@link #apply(ITaskInstanceList)} method. A rule creates temporal 
     23 * relationships between the task instances, i.e. substructures in the task tree, if 
     24 * it detects a temporal relationship and instantiates the temporal relationships accordingly. 
    2825 * </p> 
    2926 *  
    3027 * @author Patrick Harms 
    3128 */ 
    32 interface TemporalRelationshipRule { 
     29interface ITaskInstanceListScopeRule extends ITemporalRelationshipRule { 
    3330 
    3431  /** 
    3532   * <p> 
    36    * applies the rule to the given parent node. The finalize parameter is used to command the rule 
    37    * to finish rule applications, in the case it is known that no further data will be available.  
    38    * </p> 
    39    * <p> 
    40    * The returned rule application result is null, if the rule can not be applied, i.e. it does not 
    41    * detect a temporal relationship. It returns a rule application result with a status 
    42    * {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} if the rule was applied. The result 
    43    * contains all newly created parent nodes. It returns a rule application result with status 
    44    * {@link RuleApplicationStatus#RULE_APPLICATION_FEASIBLE} if the rule would be applicable if 
    45    * further children would be available in the parent node. This status MUST not be returned if  
    46    * the finalize parameter is true. In this case the rule must be applied or not.  
     33   * applies the rule to the given task instance list. The returned rule application result is null, 
     34   * if the rule can not be applied, i.e. it does not detect a temporal relationship. It returns a 
     35   * rule application result with a status {@link RuleApplicationStatus#RULE_APPLICATION_FINISHED} 
     36   * if the rule was applied. The result contains all newly created parent tasks and task instances. 
    4737   * </p> 
    4838   *  
    49    * @param parent   the parent node with the children to apply the rule on 
    50    * @param finalize true, if the rule shall not expect further children to come and that it 
    51    *                 should therefore be applied in any case 
     39   * @param taskInstances the list of task instances to apply the rule on 
    5240   *                     
    5341   * @return the rule application result as described. 
    5442   */ 
    55   RuleApplicationResult apply(ITaskTreeNode parent, 
    56                               boolean       finalize); 
     43  RuleApplicationResult apply(ITaskInstanceList taskInstances); 
    5744   
    5845} 
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationResult.java

    r1127 r1146  
    1818import java.util.List; 
    1919 
    20 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 
     20import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
     21import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
    2122 
    2223/** 
    2324 * <p> 
    24  * The rule application result describes the result of applying a {@link TemporalRelationshipRule} 
    25  * on a task tree node. It contains a {@link RuleApplicationStatus} and a list of all parent 
    26  * task tree nodes that were created during a rule application. See the description of 
    27  * {@link TemporalRelationshipRule} for more details. 
     25 * The rule application result describes the result of applying a {@link ITemporalRelationshipRule}. 
     26 * It contains a {@link RuleApplicationStatus} and a list of all parent task instances and tasks 
     27 * that were created during a rule application. See the description of 
     28 * {@link ITemporalRelationshipRule} for more details. 
    2829 * </p> 
    2930 *  
     
    3637 
    3738    /** */ 
    38     private List<ITaskTreeNode> newParents = new ArrayList<ITaskTreeNode>(); 
     39    private List<ITask> newParentTasks = new ArrayList<ITask>(); 
     40 
     41    /** */ 
     42    private List<ITaskInstance> newParentInstances = new ArrayList<ITaskInstance>(); 
    3943 
    4044    /** 
     
    6771    /** 
    6872     * <p> 
    69      * add a further parent node created during the rule application 
     73     * add a further parent task created during the rule application 
    7074     * </p> 
    7175     */ 
    72     void addNewlyCreatedParentNode(ITaskTreeNode newParent) { 
    73         newParents.add(newParent); 
     76    void addNewlyCreatedTask(ITask newParent) { 
     77        newParentTasks.add(newParent); 
    7478    } 
    7579 
    7680    /** 
    7781     * <p> 
    78      * return all parent nodes created during the rule application 
     82     * return all parent tasks created during the rule application 
    7983     * </p> 
    8084     */ 
    81     List<ITaskTreeNode> getNewlyCreatedParentNodes() { 
    82         return newParents; 
     85    List<ITask> getNewlyCreatedTasks() { 
     86        return newParentTasks; 
     87    } 
     88 
     89    /** 
     90     * <p> 
     91     * add a further parent task instance created during the rule application 
     92     * </p> 
     93     */ 
     94    void addNewlyCreatedTaskInstance(ITaskInstance newParent) { 
     95        newParentInstances.add(newParent); 
     96    } 
     97 
     98    /** 
     99     * <p> 
     100     * return all parent task instances created during the rule application 
     101     * </p> 
     102     */ 
     103    List<ITaskInstance> getNewlyCreatedTaskInstances() { 
     104        return newParentInstances; 
    83105    } 
    84106 
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleApplicationStatus.java

    r1127 r1146  
    1717/** 
    1818 * <p> 
    19  * The rule application status describes the result of applying a {@link TemporalRelationshipRule} 
    20  * on a task tree node. See the description of {@link TemporalRelationshipRule} for more details. 
     19 * The rule application status describes the result of applying a {@link ITemporalRelationshipRule}. 
     20 * See the description of {@link ITemporalRelationshipRule} for more details. 
    2121 * </p> 
    2222 *  
     
    2525enum RuleApplicationStatus { 
    2626    FINISHED, 
     27    // TODO drop feasible 
    2728    FEASIBLE, 
    2829    NOT_APPLIED; 
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/RuleUtils.java

    r1127 r1146  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
    17 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
    18 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder; 
    19 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 
    20 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory; 
     17import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
     18import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; 
     19import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
     20import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 
     21import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; 
    2122 
    2223/** 
     
    3536     *  
    3637     */ 
    37     static ISequence getSubSequenceInRange(ITaskTreeNode        parent, 
    38                                            int                   startIndex, 
    39                                            int                   endIndex, 
    40                                            String                description, 
    41                                            ITaskTreeNodeFactory  nodeFactory, 
    42                                            ITaskTreeBuilder      builder) 
     38    static ITaskInstance getSubSequenceInRange(ITaskInstanceList parent, 
     39                                               int               startIndex, 
     40                                               int               endIndex, 
     41                                               ITask             model, 
     42                                               ITaskFactory      taskFactory, 
     43                                               ITaskBuilder      taskBuilder) 
    4344    { 
    44         ISequence sequence = nodeFactory.createNewSequence(); 
    45         if (description != null) { 
    46             builder.setDescription(sequence, description); 
     45        ITaskInstance subsequence = taskFactory.createNewTaskInstance(model); 
     46 
     47        for (int i = startIndex; i <= endIndex; i++) { 
     48            taskBuilder.addChild(subsequence, parent.get(i)); 
    4749        } 
    4850 
    49         for (int i = startIndex; i <= endIndex; i++) { 
    50             builder.addChild(sequence, parent.getChildren().get(i)); 
    51         } 
    52  
    53         return sequence; 
     51        return subsequence; 
    5452    } 
    5553 
     
    5755     *  
    5856     */ 
    59     static ISequence createNewSubSequenceInRange(ITaskTreeNode        parent, 
    60                                                  int                   startIndex, 
    61                                                  int                   endIndex, 
    62                                                  String                description, 
    63                                                  ITaskTreeNodeFactory  nodeFactory, 
    64                                                  ITaskTreeBuilder      builder) 
     57    static ITaskInstance createNewSubSequenceInRange(ITaskInstanceList parent, 
     58                                                     int               startIndex, 
     59                                                     int               endIndex, 
     60                                                     ITask             model, 
     61                                                     ITaskFactory      taskFactory, 
     62                                                     ITaskBuilder      taskBuilder) 
    6563    { 
    66         ISequence sequence = nodeFactory.createNewSequence(); 
    67         if (description != null) { 
    68             builder.setDescription(sequence, description); 
     64        ITaskInstance subsequence = taskFactory.createNewTaskInstance(model); 
     65 
     66        for (int i = startIndex; i <= endIndex; i++) { 
     67            taskBuilder.addChild(subsequence, parent.get(startIndex)); 
     68            taskBuilder.removeTaskInstance(parent, startIndex); 
    6969        } 
    7070 
    71         for (int i = startIndex; i <= endIndex; i++) { 
    72             builder.addChild(sequence, parent.getChildren().get(startIndex)); 
    73             builder.removeChild((ISequence) parent, startIndex); 
    74         } 
    7571 
    76         builder.addChild((ISequence) parent, startIndex, sequence); 
     72        taskBuilder.addTaskInstance(parent, startIndex, subsequence); 
    7773 
    78         return sequence; 
     74        return subsequence; 
    7975    } 
    8076 
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java

    r1133 r1146  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
     17import java.util.HashMap; 
    1718import java.util.Iterator; 
    1819import java.util.LinkedList; 
    1920import java.util.List; 
    2021 
    21 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 
    22 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; 
     22import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality; 
     23import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager; 
     24import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    2325import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 
    2426import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 
    2527import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 
    26 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder; 
    27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 
    28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
     29import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; 
     30import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; 
     31import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
     32import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 
     33import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
     34import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator; 
    2935import de.ugoe.cs.autoquest.usageprofiles.Trie; 
    3036import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor; 
    3137import de.ugoe.cs.util.StopWatch; 
    32 import de.ugoe.cs.util.console.Console; 
    3338 
    3439/** 
     
    3944 * @author Patrick Harms 
    4045 */ 
    41 class SequenceForTaskDetectionRule implements TemporalRelationshipRule { 
     46class SequenceForTaskDetectionRule implements ISessionScopeRule { 
    4247     
    4348    /** 
    4449     * <p> 
    45      * the task tree node factory to be used for creating substructures for the temporal 
     50     * the task factory to be used for creating substructures for the temporal 
    4651     * relationships identified during rule 
    4752     * </p> 
    4853     */ 
    49     private ITaskTreeNodeFactory taskTreeNodeFactory; 
     54    private ITaskFactory taskFactory; 
    5055    /** 
    5156     * <p> 
    52      * the task tree builder to be used for creating substructures for the temporal relationships 
     57     * the task builder to be used for creating substructures for the temporal relationships 
    5358     * identified during rule application 
    5459     * </p> 
    5560     */ 
    56     private ITaskTreeBuilder taskTreeBuilder; 
     61    private ITaskBuilder taskBuilder; 
    5762 
    5863    /** 
    5964     * <p> 
    60      * the node comparator to be used for comparing task tree nodes 
     65     * the task comparator to be used for comparing tasks 
    6166     * </p> 
    6267     */ 
    63     private TaskTreeNodeComparator nodeComparator; 
     68    private TaskComparator taskComparator; 
    6469 
    6570    /** 
    6671     * <p> 
    67      * instantiates the rule and initializes it with a node equality rule manager and the minimal 
    68      * node equality identified sublist must have to consider them as iterated. 
     72     * instantiates the rule and initializes it with a task equality rule manager and the minimal 
     73     * task equality identified sublist must have to consider them as iterated. 
    6974     * </p> 
    7075     */ 
    71     SequenceForTaskDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager, 
    72                                  NodeEquality            minimalNodeEquality, 
    73                                  ITaskTreeNodeFactory    taskTreeNodeFactory, 
    74                                  ITaskTreeBuilder        taskTreeBuilder) 
     76    SequenceForTaskDetectionRule(TaskEqualityRuleManager taskEqualityRuleManager, 
     77                                 TaskEquality            minimalTaskEquality, 
     78                                 ITaskFactory            taskFactory, 
     79                                 ITaskBuilder            taskBuilder) 
    7580    { 
    76         this.taskTreeNodeFactory = taskTreeNodeFactory; 
    77         this.taskTreeBuilder = taskTreeBuilder; 
    78          
    79         this.nodeComparator = 
    80             new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality); 
     81        this.taskFactory = taskFactory; 
     82        this.taskBuilder = taskBuilder; 
     83         
     84        this.taskComparator = new TaskComparator(taskEqualityRuleManager, minimalTaskEquality); 
    8185    } 
    8286 
     
    8993    } 
    9094 
    91     /* 
    92      * (non-Javadoc) 
    93      *  
    94      * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, 
    95      * boolean) 
     95    /* (non-Javadoc) 
     96     * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply(java.util.List) 
    9697     */ 
    9798    @Override 
    98     public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) { 
    99         if (!(parent instanceof ISequence)) { 
    100             return null; 
    101         } 
    102  
    103         if (!finalize) { 
    104             // the rule is always feasible as tasks may occur at any time 
    105             RuleApplicationResult result = new RuleApplicationResult(); 
    106             result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 
    107             return result; 
    108         } 
    109  
    110         List<ITaskTreeNode> children = parent.getChildren(); 
    111         List<ISequence> sessions = new LinkedList<ISequence>(); 
    112          
    113         for (ITaskTreeNode child : children) { 
    114             if (child instanceof ISequence) { 
    115                 sessions.add((ISequence) child); 
    116             } 
    117             else { 
    118                 Console.println("provided parent is no parent of sessions"); 
    119                 return null; 
    120             } 
    121         } 
    122          
     99    public RuleApplicationResult apply(List<IUserSession> sessions) { 
    123100        RuleApplicationData appData = new RuleApplicationData(sessions); 
    124101 
    125         boolean finished = false; 
    126          
    127102        // this is the real rule application. Loop while something is replaced. 
    128103        do { 
     
    137112            appData.getStopWatch().stop("whole loop"); 
    138113             
    139             //((TaskTreeNodeComparator) nodeComparator).getStopWatch().dumpStatistics(System.out); 
    140             //((TaskTreeNodeComparator) nodeComparator).getStopWatch().reset(); 
     114            //((TaskTreeNodeComparator) taskComparator).getStopWatch().dumpStatistics(System.out); 
     115            //((TaskTreeNodeComparator) taskComparator).getStopWatch().reset(); 
    141116             
    142117            appData.getStopWatch().dumpStatistics(System.out); 
    143118            appData.getStopWatch().reset(); 
    144119             
    145             finished = (appData.getReplacementCounter() == 0); 
    146         } 
    147         while (!finished); 
    148          
    149         System.out.println("created " + appData.getResult().getNewlyCreatedParentNodes().size() + 
    150                            " new parent nodes\n"); 
    151          
    152         if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) { 
     120        } 
     121        while (appData.detectedAndReplacedTasks()); 
     122         
     123        System.out.println 
     124            ("created " + appData.getResult().getNewlyCreatedTasks().size() + 
     125             " new tasks and " + appData.getResult().getNewlyCreatedTaskInstances().size() + 
     126             " appropriate instances\n"); 
     127         
     128        if ((appData.getResult().getNewlyCreatedTasks().size() > 0) || 
     129            (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) 
     130        { 
    153131            appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 
    154132        } 
     
    164142        appData.getStopWatch().start("detecting iterations"); 
    165143         
    166         List<ISequence> sessions = appData.getSessions(); 
    167         int foundIterations = 0; 
    168          
    169         for (ISequence session : sessions) { 
    170             foundIterations += detectAndReplaceIterations(session, appData); 
    171         } 
     144        List<IUserSession> sessions = appData.getSessions(); 
     145        int iteratedTasks = 0; 
     146         
     147        ITask iteratedTask = null; 
     148         
     149        do { 
     150            iteratedTask = searchIteratedTask(sessions); 
     151             
     152            if (iteratedTask != null) { 
     153                replaceIterationsOf(iteratedTask, sessions, appData); 
     154                iteratedTasks++; 
     155            } 
     156        } 
     157        while (iteratedTask != null); 
    172158         
    173159        appData.getStopWatch().stop("detecting iterations"); 
    174         System.out.println(" --> found " + foundIterations); 
    175     } 
    176  
    177     /** 
    178      * @param appData 
    179      */ 
    180     private int detectAndReplaceIterations(ISequence           session, 
    181                                            RuleApplicationData appData) 
     160        System.out.println(" --> found " + iteratedTasks + " iterated tasks"); 
     161    } 
     162 
     163    /** 
     164     * 
     165     */ 
     166    private ITask searchIteratedTask(List<IUserSession> sessions) { 
     167        for (IUserSession session : sessions) { 
     168            for (int i = 0; i < (session.size() - 1); i++) { 
     169                if (taskComparator.equals(session.get(i).getTask(), session.get(i + 1).getTask())) { 
     170                    return session.get(i).getTask(); 
     171                } 
     172            } 
     173        } 
     174         
     175        return null; 
     176    } 
     177 
     178    /** 
     179     * 
     180     */ 
     181    private void replaceIterationsOf(ITask               iteratedTask, 
     182                                     List<IUserSession>  sessions, 
     183                                     RuleApplicationData appData) 
    182184    { 
    183         int count = 0; 
    184          
    185         TemporalRelationshipRule rule = new SimpleIterationDetectionRule 
    186             (nodeComparator, taskTreeNodeFactory, taskTreeBuilder); 
    187  
    188         RuleApplicationResult result = rule.apply(session, true); 
    189              
    190         if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) { 
    191             for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { 
    192                 appData.getResult().addNewlyCreatedParentNode(newParent); 
    193                 if (newParent instanceof IIteration) { 
    194                     count++; 
    195                 } 
    196             } 
    197         } 
    198          
    199         return count; 
     185        IIteration iteration = taskFactory.createNewIteration(); 
     186        ITaskInstance iterationInstance = null; 
     187         
     188        List<ITaskInstance> iterationInstances = new LinkedList<ITaskInstance>(); 
     189         
     190        for (IUserSession session : sessions) { 
     191            int index = 0; 
     192            while (index < session.size()) { 
     193                if (taskComparator.equals(iteratedTask, session.get(index).getTask())) { 
     194                    if (iterationInstance == null) { 
     195                        iterationInstance = taskFactory.createNewTaskInstance(iteration); 
     196                        iterationInstances.add(iterationInstance); 
     197                        taskBuilder.addTaskInstance(session, index, iterationInstance); 
     198                        index++; 
     199                    } 
     200                     
     201                    taskBuilder.addChild(iterationInstance, session.get(index)); 
     202                    taskBuilder.removeTaskInstance(session, index); 
     203                } 
     204                else { 
     205                    if (iterationInstance != null) { 
     206                        iterationInstance = null; 
     207                    } 
     208                    index++; 
     209                } 
     210            } 
     211        } 
     212         
     213        harmonizeIterationInstancesModel(iteration, iterationInstances); 
     214    } 
     215 
     216    /** 
     217     * <p> 
     218     * TODO: comment 
     219     * </p> 
     220     * 
     221     * @param iteratedTaskVariants 
     222     */ 
     223    private void harmonizeIterationInstancesModel(IIteration          iteration, 
     224                                                  List<ITaskInstance> iterationInstances) 
     225    { 
     226        List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
     227         
     228        // merge the lexically different variants of iterated task to a unique list  
     229        for (ITaskInstance iterationInstance : iterationInstances) { 
     230            for (ITaskInstance executionVariant : iterationInstance) { 
     231                ITask candidate = executionVariant.getTask(); 
     232             
     233                boolean found = false; 
     234                for (ITask taskVariant : iteratedTaskVariants) { 
     235                    if (taskComparator.areLexicallyEqual(taskVariant, candidate)) { 
     236                        taskBuilder.setTask(executionVariant, taskVariant); 
     237                        found = true; 
     238                        break; 
     239                    } 
     240                } 
     241                 
     242                if (!found) { 
     243                    iteratedTaskVariants.add(candidate); 
     244                } 
     245            } 
     246        } 
     247         
     248        // if there are more than one lexically different variant of iterated tasks, adapt the 
     249        // iteration model to be a selection of different variants. In this case also adapt 
     250        // the generated iteration instances to correctly contain selection instances. If there 
     251        // is only one variant of an iterated task, simply set this as the marked task of the 
     252        // iteration. In this case, the instances can be preserved as is 
     253        if (iteratedTaskVariants.size() > 1) { 
     254            ISelection selection = taskFactory.createNewSelection(); 
     255             
     256            for (ITask variant : iteratedTaskVariants) { 
     257                taskBuilder.addChild(selection, variant); 
     258            } 
     259             
     260            taskBuilder.setMarkedTask(iteration, selection); 
     261             
     262            for (ITaskInstance instance : iterationInstances) { 
     263                for (int i = 0; i < instance.size(); i++) { 
     264                    ITaskInstance selectionInstance = taskFactory.createNewTaskInstance(selection); 
     265                    taskBuilder.addChild(selectionInstance, instance.get(i)); 
     266                    taskBuilder.setTaskInstance(instance, i, selectionInstance); 
     267                } 
     268            } 
     269        } 
     270        else { 
     271            taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
     272        } 
    200273    } 
    201274 
     
    226299        Tasks tasks; 
    227300        boolean createNewTrie = (appData.getLastTrie() == null) || 
    228             appData.getReplacementCounter() > 0; // tree has changed 
     301            appData.detectedAndReplacedTasks(); // tree has changed 
    229302         
    230303        do { 
     
    240313            createNewTrie = false; 
    241314             
    242             for (List<ITaskTreeNode> task : tasks) { 
     315            for (List<ITaskInstance> task : tasks) { 
    243316                if (task.size() >= appData.getTrainedSequenceLength()) { 
    244317                    // Trie must be recreated with a longer sequence length to be sure that 
     
    267340 
    268341        appData.getStopWatch().start("training trie"); 
    269         appData.setLastTrie(new Trie<ITaskTreeNode>(nodeComparator)); 
     342        appData.setLastTrie(new Trie<ITaskInstance>(taskComparator)); 
    270343     
    271         List<ISequence> sessions = appData.getSessions(); 
    272          
    273         for (ISequence session : sessions) { 
     344        List<IUserSession> sessions = appData.getSessions(); 
     345         
     346        for (IUserSession session : sessions) { 
    274347            trainTrie(session, appData); 
    275348        } 
     
    282355     * @param parent 
    283356     */ 
    284     private void trainTrie(ISequence session, RuleApplicationData appData) { 
    285         List<ITaskTreeNode> children = session.getChildren(); 
     357    private void trainTrie(IUserSession session, RuleApplicationData appData) { 
     358        List<ITaskInstance> children = session.getExecutedTasks(); 
    286359         
    287360        if ((children != null) && (children.size() > 0)) { 
     
    294367     */ 
    295368    private void replaceSequencesOccurringMostOften(RuleApplicationData appData) { 
    296         appData.resetReplacementCounter(); 
     369        appData.detectedAndReplacedTasks(false); 
    297370 
    298371        if ((appData.getLastFoundTasks().size() > 0) && 
    299372            (appData.getLastFoundTasks().getOccurrenceCount() > 1)) 
    300373        { 
    301             System.out.println("replacing tasks occurrences with merged variants of all versions"); 
    302  
    303             for (List<ITaskTreeNode> task : appData.getLastFoundTasks()) { 
    304                 String taskId = "task " + RuleUtils.getNewId(); 
    305                 System.out.println("replacing " + taskId + ": " + task); 
    306  
    307                 appData.clearTaskOccurrences(); 
    308                 determineVariantsOfTaskOccurrences(task, appData.getSessions(), appData); 
    309                  
    310                 appData.getStopWatch().start("merging task nodes"); 
    311                 ITaskTreeNode taskReplacement = mergeVariantsOfTaskOccurrence(taskId, appData); 
    312                 appData.getStopWatch().stop("merging task nodes"); 
    313  
    314                 appData.resetReplacementCounter(); 
    315                 replaceTaskOccurrences(task, taskReplacement, appData.getSessions(), appData); 
    316  
    317                 if (appData.getReplacementCounter() > 0) { 
    318                     appData.getResult().addNewlyCreatedParentNode(taskReplacement); 
    319                 } 
    320  
    321                 if (appData.getReplacementCounter() < 
    322                     appData.getLastFoundTasks().getOccurrenceCount()) 
    323                 { 
    324                     System.out.println(taskId + ": replaced task only " + 
    325                                        appData.getReplacementCounter() + 
    326                                        " times instead of expected " + 
     374            System.out.println("replacing tasks occurrences"); 
     375 
     376            for (List<ITaskInstance> task : appData.getLastFoundTasks()) { 
     377                ISequence sequence = taskFactory.createNewSequence(); 
     378                 
     379                System.out.println("replacing " + sequence.getId() + ": " + task); 
     380 
     381                List<ITaskInstance> sequenceInstances = 
     382                    replaceTaskOccurrences(task, appData.getSessions(), sequence); 
     383                 
     384                harmonizeSequenceInstancesModel(sequence, sequenceInstances,task.size()); 
     385                appData.detectedAndReplacedTasks(sequenceInstances.size() > 0); 
     386 
     387                if (sequenceInstances.size() < appData.getLastFoundTasks().getOccurrenceCount()) { 
     388                    System.out.println(sequence.getId() + ": replaced task only " + 
     389                                       sequenceInstances.size() + " times instead of expected " + 
    327390                                       appData.getLastFoundTasks().getOccurrenceCount()); 
    328391                } 
     
    333396 
    334397    /** 
    335      * @param tree 
    336      */ 
    337     private void determineVariantsOfTaskOccurrences(List<ITaskTreeNode> task, 
    338                                                     List<ISequence>     sessions, 
    339                                                     RuleApplicationData appData) 
     398     * 
     399     */ 
     400    private void harmonizeSequenceInstancesModel(ISequence           sequence, 
     401                                                 List<ITaskInstance> sequenceInstances, 
     402                                                 int                 sequenceLength) 
    340403    { 
    341         for (ISequence session : sessions) { 
    342             int index = -1; 
    343                  
    344             List<ITaskTreeNode> children = session.getChildren(); 
    345  
    346             do { 
    347                 index = getSubListIndex(children, task, ++index); 
    348  
    349                 if (index > -1) { 
    350                     ISequence taskOccurrence = RuleUtils.getSubSequenceInRange 
    351                             (session, index, index + task.size() - 1, null, 
    352                              taskTreeNodeFactory, taskTreeBuilder); 
    353  
    354                     appData.addTaskOccurrence(taskOccurrence); 
    355  
    356                     // let the index point to the last element the belongs the identified occurrence 
    357                     index += task.size() - 1; 
    358                 } 
    359             } 
    360             while (index > -1); 
    361         } 
    362     } 
    363  
    364     /** 
    365      * @param appData 
    366      * @return 
    367      */ 
    368     private ITaskTreeNode mergeVariantsOfTaskOccurrence(String              taskId, 
    369                                                         RuleApplicationData appData) 
    370     { 
    371         return mergeVariantsOfTasks(taskId, appData.getTaskOccurrences()); 
    372     } 
    373  
    374     /** 
    375      * @param appData 
    376      * @return 
    377      */ 
    378     private ITaskTreeNode mergeVariantsOfTasks(String description, List<ITaskTreeNode> variants) { 
    379         // merge but preserve lexically distinct variants 
    380         TaskTreeNodeMerger merger = new TaskTreeNodeMerger 
    381             (taskTreeNodeFactory, taskTreeBuilder, nodeComparator); 
    382          
    383         merger.mergeTaskNodes(variants); 
    384          
    385         if (variants.size() == 1) { 
    386             ITaskTreeNode replacement = variants.get(0); 
    387             taskTreeBuilder.setDescription(replacement, description); 
    388             return replacement; 
    389         } 
    390         else { 
    391             ISelection selection = taskTreeNodeFactory.createNewSelection(); 
    392             taskTreeBuilder.setDescription(selection, "variants of task " + description); 
    393              
    394             for (ITaskTreeNode variant : variants) { 
    395                 taskTreeBuilder.addChild(selection, variant); 
    396             } 
    397              
    398             return selection; 
    399         } 
    400     } 
    401  
    402     /** 
    403      * @param task 
    404      * @param parent 
    405      * @param treeBuilder 
    406      * @param nodeFactory 
    407      * @param result 
    408      */ 
    409     private void replaceTaskOccurrences(List<ITaskTreeNode> task, 
    410                                         ITaskTreeNode       replacement, 
    411                                         List<ISequence>     sessions, 
    412                                         RuleApplicationData appData) 
    413     { 
    414         // now check the children themselves for an occurrence of the task 
    415         for (int i = 0; i < sessions.size(); i++) { 
    416             ISequence session = sessions.get(i); 
    417              
    418             int index = -1; 
    419          
    420             List<ITaskTreeNode> children = session.getChildren(); 
    421  
    422             do { 
    423                 index = getSubListIndex(children, task, ++index); 
    424  
    425                 if (index > -1) { 
    426                     if ((!(replacement instanceof ISequence)) || 
    427                         (task.size() < children.size())) 
    428                     { 
    429                         for (int j = index; j < index + task.size(); j++) { 
    430                             taskTreeBuilder.removeChild(session, index); 
    431                         } 
    432  
    433                         taskTreeBuilder.addChild(session, index, replacement); 
    434                         appData.incrementReplacementCounter(); 
    435  
    436                         children = session.getChildren(); 
    437                     } 
    438                     else { 
    439                         // the whole list of children is an occurrence of this task. So ask the 
    440                         // caller of the method to replace the whole node 
    441                         sessions.set(i, (ISequence) replacement); 
    442                         appData.incrementReplacementCounter(); 
     404         
     405        // ensure for each subtask that lexically different variants are preserved 
     406        for (int subTaskIndex = 0; subTaskIndex < sequenceLength; subTaskIndex++) { 
     407            List<ITask> subTaskVariants = new LinkedList<ITask>(); 
     408             
     409            for (ITaskInstance sequenceInstance : sequenceInstances) { 
     410                ITask candidate = sequenceInstance.get(subTaskIndex).getTask(); 
     411                 
     412                boolean found = false; 
     413                 
     414                for (int i = 0; i < subTaskVariants.size(); i++) { 
     415                    if (taskComparator.areLexicallyEqual(subTaskVariants.get(i), candidate)) { 
     416                        taskBuilder.setTask 
     417                            (sequenceInstance.get(subTaskIndex), subTaskVariants.get(i)); 
     418                         
     419                        found = true; 
    443420                        break; 
    444421                    } 
    445422                } 
     423                 
     424                if (!found) { 
     425                    subTaskVariants.add(candidate); 
     426                } 
     427            } 
     428             
     429            // if there are more than one lexically different variant of the sub task at 
     430            // the considered position, adapt the sequence model at that position to have 
     431            // a selection of the different variants. In this case also adapt the 
     432            // generated sequence instances to correctly contain selection instances. If 
     433            // there is only one variant of sub tasks at the given position, simply set 
     434            // this variant as the sub task of the selection. In this case, the instances 
     435            // can be preserved as is 
     436            if (subTaskVariants.size() > 1) { 
     437                ISelection selection = taskFactory.createNewSelection(); 
     438                 
     439                for (ITask variant : subTaskVariants) { 
     440                    taskBuilder.addChild(selection, variant); 
     441                } 
     442                 
     443                taskBuilder.addChild(sequence, selection); 
     444                 
     445                for (ITaskInstance instance : sequenceInstances) { 
     446                    ITaskInstance selectionInstance = 
     447                        taskFactory.createNewTaskInstance(selection); 
     448                    taskBuilder.addChild(selectionInstance, instance.get(subTaskIndex)); 
     449                    taskBuilder.setTaskInstance(instance, subTaskIndex, selectionInstance); 
     450                } 
     451            } 
     452            else if (subTaskVariants.size() == 1) { 
     453                taskBuilder.addChild(sequence, subTaskVariants.get(0)); 
     454            } 
     455        } 
     456    } 
     457 
     458    /** 
     459     * @param tree 
     460     */ 
     461    private List<ITaskInstance> replaceTaskOccurrences(List<ITaskInstance> task, 
     462                                                       List<IUserSession>  sessions, 
     463                                                       ISequence           temporalTaskModel) 
     464    { 
     465        List<ITaskInstance> sequenceInstances = new LinkedList<ITaskInstance>(); 
     466         
     467        for (IUserSession session : sessions) { 
     468            int index = -1; 
     469                 
     470            do { 
     471                index = getSubListIndex(session, task, ++index); 
     472 
     473                if (index > -1) { 
     474                    sequenceInstances.add 
     475                        (RuleUtils.createNewSubSequenceInRange 
     476                             (session, index, index + task.size() - 1, temporalTaskModel, 
     477                              taskFactory, taskBuilder)); 
     478                } 
    446479            } 
    447480            while (index > -1); 
    448481        } 
     482         
     483        return sequenceInstances; 
    449484    } 
    450485 
     
    454489     * @return 
    455490     */ 
    456     private int getSubListIndex(List<ITaskTreeNode> list, 
    457                                 List<ITaskTreeNode> subList, 
     491    private int getSubListIndex(ITaskInstanceList  list, 
     492                                List<ITaskInstance> subList, 
    458493                                int                 startIndex) 
    459494    { 
     
    465500             
    466501            for (int j = 0; j < subList.size(); j++) { 
    467                 if (!nodeComparator.equals(list.get(i + j), subList.get(j))) { 
     502                if (!taskComparator.equals(list.get(i + j), subList.get(j))) { 
    468503                    matchFound = false; 
    469504                    break; 
     
    479514        return result; 
    480515    } 
     516 
     517    /** 
     518     * @param trie 
     519     * @param object 
     520     * @return 
     521     */ 
     522    private int getSubListIndex(List<ITaskInstance> list, 
     523                                List<ITaskInstance> subList, 
     524                                int                 startIndex) 
     525    { 
     526        boolean matchFound; 
     527        int result = -1; 
     528         
     529        for (int i = startIndex; i <= list.size() - subList.size(); i++) { 
     530            matchFound = true; 
     531             
     532            for (int j = 0; j < subList.size(); j++) { 
     533                if (!taskComparator.equals(list.get(i + j), subList.get(j))) { 
     534                    matchFound = false; 
     535                    break; 
     536                } 
     537            } 
     538             
     539            if (matchFound) { 
     540                result = i; 
     541                break; 
     542            } 
     543        } 
     544         
     545        return result; 
     546    } 
    481547     
    482548    /** 
    483549     * @author Patrick Harms 
    484550     */ 
    485     private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskTreeNode> { 
     551    private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskInstance> { 
    486552         
    487553        /** 
     
    493559         *  
    494560         */ 
    495         private List<List<ITaskTreeNode>> foundTasks = new LinkedList<List<ITaskTreeNode>>(); 
     561        private List<List<ITaskInstance>> foundTasks = new LinkedList<List<ITaskInstance>>(); 
    496562 
    497563        /** 
     
    507573         */ 
    508574        @Override 
    509         public TrieProcessor.Result process(List<ITaskTreeNode> task, int count) { 
    510             if (task.size() < 2) { 
    511                 // ignore single nodes 
     575        public TrieProcessor.Result process(List<ITaskInstance> foundTask, int count) { 
     576            if (foundTask.size() < 2) { 
     577                // ignore single tasks 
    512578                return TrieProcessor.Result.CONTINUE; 
    513579            } 
     
    519585 
    520586            if (this.currentCount > count) { 
    521                 // ignore this children of this node, as they may have only smaller counts than 
     587                // ignore this children of this task, as they may have only smaller counts than 
    522588                // the already found tasks 
    523589                return TrieProcessor.Result.SKIP_NODE; 
     
    536602                boolean added = false; 
    537603                for (int i = 0; i < foundTasks.size(); i++) { 
    538                     if (foundTasks.get(i).size() < task.size()) { 
     604                    if (foundTasks.get(i).size() < foundTask.size()) { 
    539605                        // defensive copy 
    540                         foundTasks.add(i, new LinkedList<ITaskTreeNode>(task)); // defensive copy 
     606                        foundTasks.add(i, new LinkedList<ITaskInstance>(foundTask)); // defensive copy 
    541607                        added = true; 
    542608                        break; 
     
    545611                 
    546612                if (!added) { 
    547                     foundTasks.add(new LinkedList<ITaskTreeNode>(task)); // defensive copy 
     613                    foundTasks.add(new LinkedList<ITaskInstance>(foundTask)); // defensive copy 
    548614                } 
    549615            } 
     
    571637                        // found a task that is a potential subtask. Check for this and remove the 
    572638                        // subtask if needed 
    573                         List<ITaskTreeNode> longTask = foundTasks.get(i); 
    574                         List<ITaskTreeNode> shortTask = foundTasks.get(j); 
     639                        List<ITaskInstance> longTask = foundTasks.get(i); 
     640                        List<ITaskInstance> shortTask = foundTasks.get(j); 
    575641                         
    576642                        if (getSubListIndex(longTask, shortTask, 0) > -1) { 
     
    598664         *  
    599665         */ 
    600         private List<ISequence> sessions; 
    601          
    602         /** 
    603          *  
    604          */ 
    605         private Trie<ITaskTreeNode> lastTrie; 
     666        private List<IUserSession> sessions; 
     667         
     668        /** 
     669         *  
     670         */ 
     671        private Trie<ITaskInstance> lastTrie; 
    606672         
    607673        /** 
     
    618684         *  
    619685         */ 
    620         private List<ITaskTreeNode> taskOccurrences = new LinkedList<ITaskTreeNode>(); 
    621          
    622         /** 
    623          *  
    624          */ 
    625         private int replacementCounter; 
     686        private boolean detectedAndReplacedTasks; 
    626687         
    627688        /** 
     
    638699         *  
    639700         */ 
    640         private RuleApplicationData(List<ISequence> sessions) { 
     701        private RuleApplicationData(List<IUserSession> sessions) { 
    641702            this.sessions = sessions; 
    642703        } 
     
    645706         * @return the tree 
    646707         */ 
    647         private List<ISequence> getSessions() { 
     708        private List<IUserSession> getSessions() { 
    648709            return sessions; 
    649710        } 
     
    652713         * @param lastTrie the lastTrie to set 
    653714         */ 
    654         private void setLastTrie(Trie<ITaskTreeNode> lastTrie) { 
     715        private void setLastTrie(Trie<ITaskInstance> lastTrie) { 
    655716            this.lastTrie = lastTrie; 
    656717        } 
     
    659720         * @return the lastTrie 
    660721         */ 
    661         private Trie<ITaskTreeNode> getLastTrie() { 
     722        private Trie<ITaskInstance> getLastTrie() { 
    662723            return lastTrie; 
    663724        } 
     
    692753 
    693754        /** 
    694          * @return the taskOccurrences 
    695          */ 
    696         private void clearTaskOccurrences() { 
    697             taskOccurrences.clear(); 
    698         } 
    699  
    700         /** 
    701          * @return the taskOccurrences 
    702          */ 
    703         private void addTaskOccurrence(ITaskTreeNode taskOccurrence) { 
    704             taskOccurrences.add(taskOccurrence); 
    705         } 
    706  
    707         /** 
    708          * @return the taskOccurrences 
    709          */ 
    710         private List<ITaskTreeNode> getTaskOccurrences() { 
    711             return taskOccurrences; 
    712         } 
    713  
    714         /** 
    715755         * 
    716756         */ 
    717         private void resetReplacementCounter() { 
    718             replacementCounter = 0; 
     757        private void detectedAndReplacedTasks(boolean detectedAndReplacedTasks) { 
     758            this.detectedAndReplacedTasks = detectedAndReplacedTasks; 
    719759        } 
    720760 
     
    722762         * 
    723763         */ 
    724         private void incrementReplacementCounter() { 
    725             replacementCounter++; 
    726         } 
    727  
    728         /** 
    729          * 
    730          */ 
    731         private int getReplacementCounter() { 
    732             return replacementCounter; 
     764        private boolean detectedAndReplacedTasks() { 
     765            return detectedAndReplacedTasks; 
    733766        } 
    734767         
     
    753786     * @author Patrick Harms 
    754787     */ 
    755     private static class Tasks implements Iterable<List<ITaskTreeNode>> { 
     788    private static class Tasks implements Iterable<List<ITaskInstance>> { 
    756789         
    757790        /** 
     
    763796         *  
    764797         */ 
    765         private List<List<ITaskTreeNode>> sequences; 
     798        private List<List<ITaskInstance>> sequences; 
    766799 
    767800        /** 
     
    769802         * @param sequences 
    770803         */ 
    771         private Tasks(int occurrenceCount, List<List<ITaskTreeNode>> sequences) { 
     804        private Tasks(int occurrenceCount, List<List<ITaskInstance>> sequences) { 
    772805            super(); 
    773806            this.occurrenceCount = occurrenceCount; 
     
    797830         */ 
    798831        @Override 
    799         public Iterator<List<ITaskTreeNode>> iterator() { 
     832        public Iterator<List<ITaskInstance>> iterator() { 
    800833            return this.sequences.iterator(); 
    801834        } 
     
    803836    } 
    804837 
     838    /** 
     839     * 
     840     */ 
     841    private class TaskComparator implements SymbolComparator<ITaskInstance> { 
     842 
     843        /** */ 
     844        private Comparer comparer; 
     845 
     846        /** */ 
     847        private Comparer lexicalComparer; 
     848 
     849        /** */ 
     850        private HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>(); 
     851 
     852        /** */ 
     853        private HashMap<Long, Boolean> lexicalEqualityBuffer; 
     854 
     855        /** 
     856         * 
     857         */ 
     858        public TaskComparator(TaskEqualityRuleManager taskEqualityRuleManager, 
     859                              TaskEquality            minimalNodeEquality) 
     860        { 
     861            super(); 
     862             
     863            if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) { 
     864                comparer = new LexicalComparer(taskEqualityRuleManager); 
     865            } 
     866            else if (minimalNodeEquality == TaskEquality.SYNTACTICALLY_EQUAL) { 
     867                comparer = new SyntacticalComparer(taskEqualityRuleManager); 
     868            } 
     869            else if (minimalNodeEquality == TaskEquality.SEMANTICALLY_EQUAL) { 
     870                comparer = new SemanticalComparer(taskEqualityRuleManager); 
     871            } 
     872            else { 
     873                comparer = new DefaultComparer(taskEqualityRuleManager, minimalNodeEquality); 
     874            } 
     875             
     876            if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) { 
     877                lexicalComparer = comparer; 
     878                lexicalEqualityBuffer = equalityBuffer; 
     879            } 
     880            else { 
     881                lexicalComparer = new LexicalComparer(taskEqualityRuleManager); 
     882                lexicalEqualityBuffer = new HashMap<Long, Boolean>(); 
     883            } 
     884        } 
     885 
     886        /* (non-Javadoc) 
     887         * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.SymbolComparator#equals(java.lang.Object, java.lang.Object) 
     888         */ 
     889        @Override 
     890        public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) { 
     891            return equals(taskInstance1.getTask(), taskInstance2.getTask()); 
     892        }         
     893 
     894        /** 
     895         *  
     896         */ 
     897        public boolean equals(ITask task1, ITask task2) { 
     898            Boolean result; 
     899             
     900            if (task1 != task2) { 
     901                if ((task1 instanceof IEventTask) && (task2 instanceof IEventTask)) { 
     902                    long key = ((long) System.identityHashCode(task1)) << 32; 
     903                    key += System.identityHashCode(task2); 
     904                 
     905                    result = equalityBuffer.get(key); 
     906                 
     907                    if (result == null) { 
     908                        result = comparer.compare(task1, task2); 
     909                        equalityBuffer.put(key, result); 
     910                    } 
     911                } 
     912                else { 
     913                    result = false; 
     914                } 
     915            } 
     916            else { 
     917                result = true; 
     918            } 
     919             
     920            return result; 
     921        } 
     922 
     923        /** 
     924         * 
     925         */ 
     926        public boolean areLexicallyEqual(ITask task1, ITask task2) { 
     927            Boolean result; 
     928             
     929            if (task1 != task2) { 
     930                long key = ((long) System.identityHashCode(task1)) << 32; 
     931                key += System.identityHashCode(task2); 
     932                 
     933                result = lexicalEqualityBuffer.get(key); 
     934                 
     935                if (result == null) { 
     936                    result = lexicalComparer.compare(task1, task2); 
     937                    lexicalEqualityBuffer.put(key, result); 
     938                } 
     939            } 
     940            else { 
     941                result = true; 
     942            } 
     943             
     944            return result; 
     945        } 
     946    } 
     947 
     948    /** 
     949     *  
     950     */ 
     951    private interface Comparer { 
     952         
     953        /** 
     954         *  
     955         */ 
     956        boolean compare(ITask task1, ITask task2); 
     957    } 
     958 
     959    /** 
     960     *  
     961     */ 
     962    private class LexicalComparer implements Comparer { 
     963         
     964        /** 
     965         * <p> 
     966         * the task equality manager needed for comparing tasks with each other 
     967         * </p> 
     968         */ 
     969        private TaskEqualityRuleManager taskEqualityRuleManager; 
     970         
     971        /** 
     972         * 
     973         */ 
     974        public LexicalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 
     975           this.taskEqualityRuleManager = taskEqualityRuleManager; 
     976        } 
     977         
     978        /** 
     979         *  
     980         */ 
     981        public boolean compare(ITask task1, ITask task2) { 
     982            return taskEqualityRuleManager.areLexicallyEqual(task1, task2); 
     983        } 
     984    } 
     985 
     986    /** 
     987     *  
     988     */ 
     989    private class SyntacticalComparer implements Comparer { 
     990         
     991        /** 
     992         * <p> 
     993         * the task equality manager needed for comparing tasks with each other 
     994         * </p> 
     995         */ 
     996        private TaskEqualityRuleManager taskEqualityRuleManager; 
     997         
     998        /** 
     999         * 
     1000         */ 
     1001        public SyntacticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 
     1002           this.taskEqualityRuleManager = taskEqualityRuleManager; 
     1003        } 
     1004         
     1005        /** 
     1006         *  
     1007         */ 
     1008        public boolean compare(ITask task1, ITask task2) { 
     1009            return taskEqualityRuleManager.areSyntacticallyEqual(task1, task2); 
     1010        } 
     1011    } 
     1012 
     1013    /** 
     1014     *  
     1015     */ 
     1016    private class SemanticalComparer implements Comparer { 
     1017         
     1018        /** 
     1019         * <p> 
     1020         * the task equality manager needed for comparing tasks with each other 
     1021         * </p> 
     1022         */ 
     1023        private TaskEqualityRuleManager taskEqualityRuleManager; 
     1024         
     1025        /** 
     1026         * 
     1027         */ 
     1028        public SemanticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 
     1029           this.taskEqualityRuleManager = taskEqualityRuleManager; 
     1030        } 
     1031         
     1032        /** 
     1033         *  
     1034         */ 
     1035        public boolean compare(ITask task1, ITask task2) { 
     1036            return taskEqualityRuleManager.areSemanticallyEqual(task1, task2); 
     1037        } 
     1038    } 
     1039 
     1040    /** 
     1041     *  
     1042     */ 
     1043    private class DefaultComparer implements Comparer { 
     1044         
     1045        /** 
     1046         * <p> 
     1047         * the task equality manager needed for comparing tasks with each other 
     1048         * </p> 
     1049         */ 
     1050        private TaskEqualityRuleManager taskEqualityRuleManager; 
     1051 
     1052        /** 
     1053         * <p> 
     1054         * the minimal task equality two identified sublists need to have to consider them as equal 
     1055         * </p> 
     1056         */ 
     1057        private TaskEquality minimalNodeEquality; 
     1058         
     1059        /** 
     1060         * 
     1061         */ 
     1062        public DefaultComparer(TaskEqualityRuleManager taskEqualityRuleManager, 
     1063                               TaskEquality            minimalNodeEquality) 
     1064        { 
     1065           this.taskEqualityRuleManager = taskEqualityRuleManager; 
     1066           this.minimalNodeEquality = minimalNodeEquality; 
     1067        } 
     1068         
     1069        /** 
     1070         *  
     1071         */ 
     1072        public boolean compare(ITask task1, ITask task2) { 
     1073            return taskEqualityRuleManager.areAtLeastEqual(task1, task2, minimalNodeEquality); 
     1074        } 
     1075    } 
    8051076} 
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TemporalRelationshipRuleManager.java

    r1131 r1146  
    2222import de.ugoe.cs.autoquest.eventcore.guimodel.IFrame; 
    2323import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; 
    24 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 
    25 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; 
    26 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder; 
    27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 
    28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory; 
     24import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality; 
     25import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager; 
     26import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; 
     27import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
     29import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 
     30import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 
    2931import de.ugoe.cs.util.console.Console; 
    3032 
    3133/** 
     34 * TODO update comment 
     35 *  
    3236 * <p> 
    3337 * This class is responsible for applying temporal relationship rules on a task tree. Through this, 
    3438 * a flat task tree is restructured to have more depth but to include more temporal relationships 
    35  * between task tree nodes which are not only a major sequence. I.e. through the application of 
    36  * rule iterations and selections of task tree nodes are detected. Which kind of temporal relations 
    37  * between task tree nodes are detected depends on the {@link TemporalRelationshipRule}s known to 
     39 * between tasks which are not only a major sequence. I.e. through the application of the 
     40 * rules iterations and selections of tasks are detected. Which kind of temporal relations 
     41 * between tasks are detected depends on the {@link ITaskInstanceListScopeRule}s known to 
    3842 * this class. 
    3943 * </p> 
    40  * <p>The class holds references to the appropriate {@link TemporalRelationshipRule}s and calls 
    41  * their {@link TemporalRelationshipRule#apply(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)} 
    42  * method for each node in the task tree it is needed for. The general behavior of this class is 
     44 * <p>The class holds references to the appropriate {@link ITaskInstanceListScopeRule}s and calls 
     45 * their {@link ITaskInstanceListScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
     46 * method for each task in the task tree it is needed for. The general behavior of this class is 
    4347 * the following: 
    4448 * <ol> 
     
    4852 *   </li> 
    4953 *   <li> 
    50  *     then the {@link #applyRules(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)} 
    51  *     method is called for a so far unstructured task tree node 
     54 *     then the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} 
     55 *     method is called for a so far unstructured task 
    5256 *   </li> 
    5357 *   <li> 
    5458 *     the class iterates its internal list of rules and calls their 
    55  *     {@link TemporalRelationshipRule#apply(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)} 
     59 *     {@link ITaskInstanceListScopeRule#apply(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    5660 *     method. 
    5761 *   </li> 
     
    6973 *       <li> 
    7074 *         if a rule returns, that it was applied, the same rule is applied again until it returns 
    71  *         null or feasible. For each newly created parent node provided in the rule application 
    72  *         result, the {@link #applyRules(ITaskTreeNode, ITaskTreeBuilder, ITaskTreeNodeFactory, boolean)} 
     75 *         null or feasible. For each newly created parent task provided in the rule application 
     76 *         result, the {@link #applyRules(ITask, ITaskBuilder, ITaskFactory, boolean)} 
    7377 *         method is called. 
    7478 *       </li> 
     
    7680 *   </li> 
    7781 * </ol> 
    78  * Through this, all rules are tried to be applied at least once to the provided parent node and 
    79  * all parent nodes created during the rule application. 
     82 * Through this, all rules are tried to be applied at least once to the provided parent task and 
     83 * all parent tasks created during the rule application. 
    8084 * </p> 
    8185 *  
     
    8690    /** 
    8791     * <p> 
    88      * the node equality manager needed by the rules to compare task tree nodes with each other 
    89      * </p> 
    90      */ 
    91     private NodeEqualityRuleManager nodeEqualityRuleManager; 
    92  
    93     /** 
    94      * <p> 
    95      * the task tree node factory to be used during rule application 
    96      * </p> 
    97      */ 
    98     private ITaskTreeNodeFactory taskTreeNodeFactory; 
    99  
    100     /** 
    101      * <p> 
    102      * the task tree builder to be used during rule application 
    103      * </p> 
    104      */ 
    105     private ITaskTreeBuilder taskTreeBuilder; 
     92     * the task equality manager needed by the rules to compare tasks with each other 
     93     * </p> 
     94     */ 
     95    private TaskEqualityRuleManager taskEqualityRuleManager; 
     96 
     97    /** 
     98     * <p> 
     99     * the task factory to be used during rule application 
     100     * </p> 
     101     */ 
     102    private ITaskFactory taskFactory; 
     103 
     104    /** 
     105     * <p> 
     106     * the task builder to be used during rule application 
     107     * </p> 
     108     */ 
     109    private ITaskBuilder taskBuilder; 
     110 
     111    /** 
     112     * <p> 
     113     * the temporal relationship rules known to the manager that are executed on whole sessions. 
     114     * The rules are applied in the order they occur in this list. 
     115     * </p> 
     116     */ 
     117    private ISessionScopeRule[] sessionScopeRules; 
    106118 
    107119    /** 
     
    111123     * </p> 
    112124     */ 
    113     private TemporalRelationshipRule[] treeScopeRules; 
    114  
    115     /** 
    116      * <p> 
    117      * the temporal relationship rules known to the manager that are executed on whole sub trees. 
    118      * The rules are applied in the order they occur in this list. 
    119      * </p> 
    120      */ 
    121     private TemporalRelationshipRule[] nodeScopeRules; 
     125    private ITaskInstanceListScopeRule[] taskScopeRules; 
    122126 
    123127    /** 
     
    126130     * </p> 
    127131     *  
    128      * @param nodeEqualityRuleManager the node equality rule manager to be used by the known rules 
    129      *                                for task tree node comparison during rule application 
    130      * @param taskTreeNodeFactory     the node factory to be used for instantiating new task tree 
    131      *                                nodes during rule application 
    132      * @param taskTreeBuilder         the task tree builder to be used for linking task tree nodes 
     132     * @param taskEqualityRuleManager the task equality rule manager to be used by the known rules 
     133     *                                for task comparison during rule application 
     134     * @param taskFactory             the task factory to be used for instantiating new task tree 
     135     *                                tasks during rule application 
     136     * @param taskBuilder             the task builder to be used for linking tasks 
    133137     *                                with each other during rule application 
    134138     */ 
    135     public TemporalRelationshipRuleManager(NodeEqualityRuleManager nodeEqualityRuleManager, 
    136                                            ITaskTreeNodeFactory    taskTreeNodeFactory, 
    137                                            ITaskTreeBuilder        taskTreeBuilder) 
     139    public TemporalRelationshipRuleManager(TaskEqualityRuleManager taskEqualityRuleManager, 
     140                                           ITaskFactory            taskFactory, 
     141                                           ITaskBuilder            taskBuilder) 
    138142    { 
    139143        super(); 
    140         this.nodeEqualityRuleManager = nodeEqualityRuleManager; 
    141         this.taskTreeNodeFactory = taskTreeNodeFactory; 
    142         this.taskTreeBuilder = taskTreeBuilder; 
     144        this.taskEqualityRuleManager = taskEqualityRuleManager; 
     145        this.taskFactory = taskFactory; 
     146        this.taskBuilder = taskBuilder; 
    143147    } 
    144148 
     
    146150     * <p> 
    147151     * initialized the temporal relationship rule manager by instantiating the known rules and 
    148      * providing them with a reference to the node equality manager or other information they need. 
     152     * providing them with a reference to the task equality manager or other information they need. 
    149153     * </p> 
    150154     */ 
     
    156160        //frameFilter.add(ICanvas.class); 
    157161 
    158         treeScopeRules = new TemporalRelationshipRule[] { 
     162        sessionScopeRules = new ISessionScopeRule[] { 
    159163            new SequenceForTaskDetectionRule 
    160                 (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 
    161                  taskTreeNodeFactory, taskTreeBuilder), 
     164                (taskEqualityRuleManager, TaskEquality.SEMANTICALLY_EQUAL, 
     165                 taskFactory, taskBuilder), 
    162166            /*new DefaultTaskSequenceDetectionRule 
    163                 (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 
    164                  taskTreeNodeFactory, taskTreeBuilder), 
     167                (taskEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 
     168                 taskFactory, taskTreeBuilder), 
    165169            new DefaultTaskSequenceDetectionRule 
    166                 (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 
    167                  taskTreeNodeFactory, taskTreeBuilder),*/ 
     170                (taskEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 
     171                 taskFactory, taskTreeBuilder),*/ 
    168172            /*new TreeScopeWrapperRule 
    169173                (new DefaultIterationDetectionRule 
    170                     (nodeEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 
    171                      taskTreeNodeFactory, taskTreeBuilder)), 
     174                    (taskEqualityRuleManager, NodeEquality.LEXICALLY_EQUAL, 
     175                     taskFactory, taskTreeBuilder)), 
    172176            new TreeScopeWrapperRule 
    173177                (new DefaultIterationDetectionRule 
    174                     (nodeEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 
    175                      taskTreeNodeFactory, taskTreeBuilder)), 
     178                    (taskEqualityRuleManager, NodeEquality.SYNTACTICALLY_EQUAL, 
     179                     taskFactory, taskTreeBuilder)), 
    176180            new TreeScopeWrapperRule 
    177181                (new DefaultIterationDetectionRule 
    178                     (nodeEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 
    179                      taskTreeNodeFactory, taskTreeBuilder))*/ 
     182                    (taskEqualityRuleManager, NodeEquality.SEMANTICALLY_EQUAL, 
     183                     taskFactory, taskTreeBuilder))*/ 
    180184        }; 
    181185         
    182186        //treeScopeRules.add(new DefaultGuiElementSequenceDetectionRule(frameFilter)); 
    183187 
    184         nodeScopeRules = new TemporalRelationshipRule[] { 
    185             //new SequenceOnGuiElementDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 
    186             //new EventSequenceOnSameTargetDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 
    187             new TrackBarSelectionDetectionRule 
    188                 (nodeEqualityRuleManager, taskTreeNodeFactory, taskTreeBuilder), 
    189             //new DefaultGuiEventSequenceDetectionRule(taskTreeNodeFactory, taskTreeBuilder), 
     188        taskScopeRules = new ITaskInstanceListScopeRule[] { 
     189            //new SequenceOnGuiElementDetectionRule(taskFactory, taskTreeBuilder), 
     190            //new EventSequenceOnSameTargetDetectionRule(taskFactory, taskTreeBuilder), 
     191            //new TrackBarSelectionDetectionRule(taskEqualityRuleManager, taskFactory, taskBuilder), 
     192            //new DefaultGuiEventSequenceDetectionRule(taskFactory, taskTreeBuilder), 
    190193        }; 
    191194 
     
    194197    /** 
    195198     * <p> 
    196      * applies the known rules to the provided parent node. For the creation of further nodes, 
    197      * the provided builder and node factory are utilized. The method expectes, that no more data 
     199     * applies the known rules to the provided sessions. For the creation of further tasks, 
     200     * the provided builder and task factory are utilized. The method expects, that no more data 
    198201     * is available and, therefore, finalizes the rule application. 
    199202     * </p> 
    200203     *  
    201      * @param nodeFactory  the node factory to be used for instantiating new task tree nodes. 
    202      */ 
    203     public void applyRules(ITaskTreeNode parent) { 
    204         applyRules(parent, true); 
    205     } 
    206  
    207     /** 
    208      * <p> 
    209      * applies the known rules to the provided parent node. For the creation of further nodes, 
    210      * the provided builder and node factory are utilized. If the finalize parameter is true, the 
     204     * @param taskFactory  the task factory to be used for instantiating new tasks. 
     205     */ 
     206    public void applyRules(List<IUserSession> sessions) { 
     207        applyRules(sessionScopeRules, sessions, ""); 
     208    } 
     209 
     210    /** 
     211     * <p> 
     212     * applies the known rules to the provided parent task. For the creation of further tasks, 
     213     * the provided builder and task factory are utilized. If the finalize parameter is true, the 
    211214     * rule application is finalized as far as possible without waiting for further data. If it is 
    212215     * false, the rule application is broken up at the first rule returning, that its application 
    213      * would be feasible.  
     216     * would be feasible. The method calls itself for each parent task created through the rule 
     217     * application. In this case, the finalize parameter is always true. 
    214218     * </p> 
    215219     *  
    216      * @param parent       the parent node to apply the rules on 
    217      * @param finalize     used to indicate, if the rule application shall break up if a rule would 
    218      *                     be feasible if further data was available, or not. 
    219      */ 
    220     public void applyRules(ITaskTreeNode parent, boolean finalize) { 
    221         applyRules(treeScopeRules, parent, finalize, ""); 
    222     } 
    223  
    224     /** 
    225      * <p> 
    226      * applies the known rules to the provided parent node. For the creation of further nodes, 
    227      * the provided builder and node factory are utilized. If the finalize parameter is true, the 
    228      * rule application is finalized as far as possible without waiting for further data. If it is 
    229      * false, the rule application is broken up at the first rule returning, that its application 
    230      * would be feasible. The method calls itself for each parent node created through the rule 
    231      * application. In this case, the finalize parameter is always true. 
    232      * </p> 
    233      *  
    234      * @param parent       the parent node to apply the rules on 
     220     * @param parent       the parent task to apply the rules on 
    235221     * @param finalize     used to indicate, if the rule application shall break up if a rule would 
    236222     *                     be feasible if further data was available, or not. 
     
    238224     *                     on the recursion depth of calling this method. 
    239225     */ 
    240     private int applyRules(TemporalRelationshipRule[] rules, 
    241                            ITaskTreeNode              parent, 
    242                            boolean                    finalize, 
    243                            String                     logIndent) 
     226    private int applyRules(ISessionScopeRule[] rules, 
     227                           List<IUserSession>  sessions, 
     228                           String              logIndent) 
    244229    { 
    245         Console.traceln(Level.FINER, logIndent + "applying rules for " + parent); 
     230        Console.traceln 
     231            (Level.FINER, logIndent + "applying rules for " + sessions.size() + " sessions"); 
    246232 
    247233        int noOfRuleApplications = 0; 
    248234 
    249         for (TemporalRelationshipRule rule : rules) { 
     235        for (ISessionScopeRule rule : rules) { 
    250236            RuleApplicationResult result; 
    251237            do { 
    252                 Console.traceln(Level.FINER, logIndent + "trying rule " + rule + " on " + parent); 
    253                 result = rule.apply(parent, finalize); 
     238                Console.traceln(Level.FINER, logIndent + "trying rule " + rule); 
     239                result = rule.apply(sessions); 
    254240 
    255241                if ((result != null) && 
    256242                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) 
    257243                { 
    258                     Console.traceln 
    259                         (Level.FINE, logIndent + "applied rule " + rule + " on " + parent); 
     244                    Console.traceln(Level.FINE, logIndent + "applied rule " + rule); 
    260245                    noOfRuleApplications++; 
    261246                     
    262247                    //dumpTask(parent, ""); 
    263248 
    264                     for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { 
     249                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) { 
    265250                        noOfRuleApplications += 
    266                             applyRules(nodeScopeRules, newParent, true, logIndent + "  "); 
     251                            applyRules(taskScopeRules, newParent, logIndent + "  "); 
    267252                    } 
    268253                } 
     
    271256                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
    272257 
    273             if ((!finalize) && 
    274                 (result != null) && 
    275                 (result.getRuleApplicationStatus() == RuleApplicationStatus.FEASIBLE)) 
    276             { 
    277                 // in this case, don't go on applying rules, which should not be applied yet 
    278                 break; 
    279             } 
    280258        } 
    281259 
     
    289267 
    290268    /** 
     269     * <p> 
     270     * applies the known rules to the provided parent task. For the creation of further tasks, 
     271     * the provided builder and task factory are utilized. If the finalize parameter is true, the 
     272     * rule application is finalized as far as possible without waiting for further data. If it is 
     273     * false, the rule application is broken up at the first rule returning, that its application 
     274     * would be feasible. The method calls itself for each parent task created through the rule 
     275     * application. In this case, the finalize parameter is always true. 
     276     * </p> 
     277     *  
     278     * @param parent       the parent task to apply the rules on 
     279     * @param finalize     used to indicate, if the rule application shall break up if a rule would 
     280     *                     be feasible if further data was available, or not. 
     281     * @param logIndent    simply used for logging purposes to indent the log messages depending 
     282     *                     on the recursion depth of calling this method. 
     283     */ 
     284    private int applyRules(ITaskInstanceListScopeRule[] rules, 
     285                           ITaskInstanceList            taskInstances, 
     286                           String                       logIndent) 
     287    { 
     288        Console.traceln(Level.FINER, logIndent + "applying rules for " + taskInstances.size() + 
     289                        " task instances"); 
     290 
     291        int noOfRuleApplications = 0; 
     292 
     293        for (ITaskInstanceListScopeRule rule : rules) { 
     294            RuleApplicationResult result; 
     295            do { 
     296                Console.traceln 
     297                    (Level.FINER, logIndent + "trying rule " + rule + " on " + taskInstances); 
     298                result = rule.apply(taskInstances); 
     299 
     300                if ((result != null) && 
     301                    (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)) 
     302                { 
     303                    Console.traceln 
     304                        (Level.FINE, logIndent + "applied rule " + rule + " on " + taskInstances); 
     305                    noOfRuleApplications++; 
     306                     
     307                    //dumpTask(parent, ""); 
     308 
     309                    for (ITaskInstance newParent : result.getNewlyCreatedTaskInstances()) { 
     310                        noOfRuleApplications += 
     311                            applyRules(taskScopeRules, newParent, logIndent + "  "); 
     312                    } 
     313                } 
     314            } 
     315            while ((result != null) && 
     316                   (result.getRuleApplicationStatus() == RuleApplicationStatus.FINISHED)); 
     317        } 
     318 
     319        if (noOfRuleApplications <= 0) { 
     320            Console.traceln(Level.FINE, logIndent + "no rules applied --> no temporal " + 
     321                            "relationship generated"); 
     322        } 
     323 
     324        return noOfRuleApplications; 
     325    } 
     326 
     327    /** 
    291328     * 
    292329     */ 
    293     /*private void dumpTask(ITaskTreeNode task, String indent) { 
     330    /*private void dumpTask(ITask task, String indent) { 
    294331        StringBuffer message = new StringBuffer(); 
    295332        message.append(indent); 
     
    304341         
    305342        if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { 
    306             for (ITaskTreeNode child : task.getChildren()) { 
     343            for (ITask child : task.getChildren()) { 
    307344                dumpTask(child, indent + "  "); 
    308345            } 
Note: See TracChangeset for help on using the changeset viewer.