source: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SimpleIterationDetectionRule.java @ 1133

Last change on this file since 1133 was 1127, checked in by pharms, 11 years ago
  • complete refactoring of task detection
  • many performance improvements in task detection
  • improved merging of sequences using Myers diff algorithm
File size: 7.5 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
16
17import java.util.LinkedList;
18import java.util.List;
19
20import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality;
21import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager;
22import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
23import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
27import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory;
28
29/**
30 * <p>
31 * TODO comment
32 * </p>
33 *
34 * @author Patrick Harms
35 */
36class SimpleIterationDetectionRule implements TemporalRelationshipRule {
37
38    /**
39     * <p>
40     * the task tree node factory to be used for creating substructures for the temporal
41     * relationships identified during rule
42     * </p>
43     */
44    private ITaskTreeNodeFactory taskTreeNodeFactory;
45    /**
46     * <p>
47     * the task tree builder to be used for creating substructures for the temporal relationships
48     * identified during rule application
49     * </p>
50     */
51    private ITaskTreeBuilder taskTreeBuilder;
52
53    /**
54     * <p>
55     * the node comparator used for comparing task tree nodes with each other
56     * </p>
57     */
58    private TaskTreeNodeComparator nodeComparator;
59
60    /**
61     * <p>
62     * instantiates the rule and initializes it with a node equality rule manager and the minimal
63     * node equality identified sublist must have to consider them as iterated.
64     * </p>
65     */
66    SimpleIterationDetectionRule(NodeEqualityRuleManager nodeEqualityRuleManager,
67                                 NodeEquality            minimalNodeEquality,
68                                 ITaskTreeNodeFactory    taskTreeNodeFactory,
69                                 ITaskTreeBuilder        taskTreeBuilder)
70    {
71        this.taskTreeNodeFactory = taskTreeNodeFactory;
72        this.taskTreeBuilder = taskTreeBuilder;
73       
74        this.nodeComparator =
75            new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality);
76    }
77
78    /**
79     * <p>
80     * instantiates the rule and initializes it with a node equality rule manager and the minimal
81     * node equality identified sublist must have to consider them as iterated.
82     * </p>
83     */
84    SimpleIterationDetectionRule(TaskTreeNodeComparator nodeComparator,
85                                 ITaskTreeNodeFactory   taskTreeNodeFactory,
86                                 ITaskTreeBuilder       taskTreeBuilder)
87    {
88        this.nodeComparator = nodeComparator;
89        this.taskTreeNodeFactory = taskTreeNodeFactory;
90        this.taskTreeBuilder = taskTreeBuilder;
91    }
92
93    /* (non-Javadoc)
94     * @see java.lang.Object#toString()
95     */
96    @Override
97    public String toString() {
98        return "SimpleIterationDetectionRule";
99    }
100
101    /*
102     * (non-Javadoc)
103     *
104     * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode,
105     * boolean)
106     */
107    @Override
108    public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) {
109        if (!(parent instanceof ISequence)) {
110            return null;
111        }
112       
113        if (!finalize) {
114            // this rule can only finalize whole trees
115            return null;
116        }
117
118        RuleApplicationResult result = new RuleApplicationResult();
119
120        applyOn(parent, result);
121       
122        if (result.getNewlyCreatedParentNodes().size() > 0) {
123            result.setRuleApplicationStatus(RuleApplicationStatus.FINISHED);
124        }
125
126        return result;
127    }
128
129    /**
130     *
131     */
132    private void applyOn(ITaskTreeNode node, RuleApplicationResult result) {
133        int iterationStartIndex = -1;
134        ITaskTreeNode iteratedChild = null;
135
136        int index = 0;
137        List<ITaskTreeNode> children = node.getChildren();
138       
139        while (index < children.size()) {
140            ITaskTreeNode child = children.get(index);
141
142            if (iteratedChild == null) {
143                // new iteration may start
144                iterationStartIndex = index;
145                iteratedChild = child;
146            }
147            else {
148                if (!nodeComparator.equals(iteratedChild, child)) {
149                    // iteration finished
150                    handleIteration(node, iterationStartIndex, index - 1, result);
151                   
152                    // children may have changed
153                    children = node.getChildren();
154
155                    // new iteration may start
156                    index = iterationStartIndex + 1;
157                    iterationStartIndex = index;
158                    iteratedChild = child;
159                }
160            }
161            index++;
162        }
163       
164        if (iterationStartIndex > -1) {
165            handleIteration(node, iterationStartIndex, children.size() - 1, result);
166        }
167    }
168
169    /**
170     *
171     */
172    private void handleIteration(ITaskTreeNode         parent,
173                                 int                   startIndex,
174                                 int                   endIndex,
175                                 RuleApplicationResult result)
176    {
177        if (startIndex == endIndex) {
178            // only one child
179            return;
180        }
181       
182        IIteration iteration = taskTreeNodeFactory.createNewIteration();
183        result.addNewlyCreatedParentNode(iteration);
184
185        List<ITaskTreeNode> children = parent.getChildren();
186       
187        List<ITaskTreeNode> equalChildren = new LinkedList<ITaskTreeNode>();
188           
189        for (int i = endIndex - startIndex; i >= 0; i--) {
190             equalChildren.add(children.get(startIndex));
191             taskTreeBuilder.removeChild((ISequence) parent, startIndex);
192        }
193           
194        // merge the identified variants, but preserve the differences in form of selections
195        // by using lexical equality for merge comparisons
196        TaskTreeNodeMerger merger = new TaskTreeNodeMerger
197            (taskTreeNodeFactory, taskTreeBuilder, nodeComparator);
198
199        merger.mergeTaskNodes(equalChildren);
200
201        if (equalChildren.size() == 1) {
202            taskTreeBuilder.setChild(iteration, equalChildren.get(0));
203            taskTreeBuilder.setDescription(iteration, "several " + equalChildren.get(0));
204        }
205        else {
206            taskTreeBuilder.setDescription(iteration, "several " + equalChildren.get(0));
207
208            // create a selection of all variants
209            ISelection selection = taskTreeNodeFactory.createNewSelection();
210            result.addNewlyCreatedParentNode(selection);
211            taskTreeBuilder.setChild(iteration, selection);
212            taskTreeBuilder.setDescription(selection, "variants");
213
214            for (ITaskTreeNode variant : equalChildren) {
215                taskTreeBuilder.addChild(selection, variant);
216            }
217        }
218
219        taskTreeBuilder.addChild((ISequence) parent, startIndex, iteration);
220    }
221
222}
Note: See TracBrowser for help on using the repository browser.