Ignore:
Timestamp:
03/18/13 11:46:47 (11 years ago)
Author:
pharms
Message:
  • refactoring of task tree node comparison to be able to optimize the comparisons for the different comparison levels lexically, syntactically, semantically
File:
1 edited

Legend:

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

    r1113 r1125  
    1414 
    1515package de.ugoe.cs.autoquest.tasktrees.nodeequality; 
     16 
     17import java.util.List; 
    1618 
    1719import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 
     
    5153    } 
    5254 
    53     /* 
    54      * (non-Javadoc) 
     55    /* (non-Javadoc) 
     56     * @see NodeComparisonRule#isApplicable(ITaskTreeNode, ITaskTreeNode) 
     57     */ 
     58    @Override 
     59    public boolean isApplicable(ITaskTreeNode node1, ITaskTreeNode node2) { 
     60        return (node1 instanceof ISelection) && (node2 instanceof ISelection); 
     61    } 
     62 
     63    /* (non-Javadoc) 
     64     * @see NodeComparisonRule#areLexicallyEqual(ITaskTreeNode, ITaskTreeNode) 
     65     */ 
     66    @Override 
     67    public boolean areLexicallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { 
     68        NodeEquality equality = getEquality(node1, node2, NodeEquality.LEXICALLY_EQUAL); 
     69        return (equality != null) && (equality.isAtLeast(NodeEquality.LEXICALLY_EQUAL)); 
     70    } 
     71 
     72    /* (non-Javadoc) 
     73     * @see NodeComparisonRule#areSyntacticallyEqual(ITaskTreeNode, ITaskTreeNode) 
     74     */ 
     75    @Override 
     76    public boolean areSyntacticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { 
     77        NodeEquality equality = getEquality(node1, node2, NodeEquality.SYNTACTICALLY_EQUAL); 
     78        return (equality != null) && (equality.isAtLeast(NodeEquality.SYNTACTICALLY_EQUAL)); 
     79    } 
     80 
     81    /* (non-Javadoc) 
     82     * @see NodeComparisonRule#areSemanticallyEqual(ITaskTreeNode, ITaskTreeNode) 
     83     */ 
     84    @Override 
     85    public boolean areSemanticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { 
     86        NodeEquality equality = getEquality(node1, node2, NodeEquality.SEMANTICALLY_EQUAL); 
     87        return (equality != null) && (equality.isAtLeast(NodeEquality.SEMANTICALLY_EQUAL)); 
     88    } 
     89 
     90    /* (non-Javadoc) 
     91     * @see NodeComparisonRule#compare(ITaskTreeNode, ITaskTreeNode) 
     92     */ 
     93    @Override 
     94    public NodeEquality compare(ITaskTreeNode node1, ITaskTreeNode node2) { 
     95        return getEquality(node1, node2, null); 
     96    } 
     97 
     98    /** 
    5599     *  
    56      * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode) 
    57      */ 
    58     @Override 
    59     public NodeEquality compare(ITaskTreeNode node1, ITaskTreeNode node2) { 
    60         if ((!(node1 instanceof ISelection)) || (!(node2 instanceof ISelection))) { 
    61             return null; 
    62         } 
    63  
    64         if (node1 == node2) { 
    65             return NodeEquality.IDENTICAL; 
    66         } 
    67  
    68         // if both sequences do not have children, they are identical. If only one of them has 
    69         // children, they are unequal. 
    70         if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0)) { 
     100     */ 
     101    private NodeEquality getEquality(ITaskTreeNode node1, 
     102                                     ITaskTreeNode node2, 
     103                                     NodeEquality  requiredEqualityLevel) 
     104    { 
     105        List<ITaskTreeNode> children1 = node1.getChildren(); 
     106        List<ITaskTreeNode> children2 = node2.getChildren(); 
     107 
     108        // if both selections do not have children, they are lexically equal. If only one of them 
     109        // has children, they are unequal. 
     110        if ((children1.size() == 0) && (children2.size() == 0)) { 
    71111            return NodeEquality.LEXICALLY_EQUAL; 
    72112        } 
    73         else if ((node1.getChildren().size() == 0) || (node2.getChildren().size() == 0)) { 
     113        else if ((children1.size() == 0) || (children2.size() == 0)) { 
    74114            return NodeEquality.UNEQUAL; 
    75115        } 
    76116 
    77         NodeEquality selectionEquality = NodeEquality.LEXICALLY_EQUAL; 
    78  
    79         // compare each child of selection one with each child of selection two 
     117        NodeEquality selectionEquality; 
     118 
     119        if (requiredEqualityLevel == null) { 
     120            // calculate the common equality level for all children of both selections. 
     121            // do it in both directions to ensure commutative comparison 
     122            selectionEquality = getCommonEqualityLevel(children1, children2); 
     123            if (selectionEquality != NodeEquality.UNEQUAL) { 
     124                return selectionEquality.getCommonDenominator 
     125                    (getCommonEqualityLevel(children2, children1)); 
     126            } 
     127            else { 
     128                return NodeEquality.UNEQUAL; 
     129            } 
     130        } 
     131        else { 
     132            // we are searching for a specific equality 
     133            if (checkEqualityLevel(children1, children2, requiredEqualityLevel) && 
     134                checkEqualityLevel(children2, children1, requiredEqualityLevel)) 
     135            { 
     136                return requiredEqualityLevel; 
     137            } 
     138            else { 
     139                return NodeEquality.UNEQUAL; 
     140            } 
     141        } 
     142    } 
     143 
     144    /** 
     145     * <p> 
     146     * TODO: comment 
     147     * </p> 
     148     * 
     149     * @param children1 
     150     * @param children2 
     151     * @param requiredEqualityLevel 
     152     */ 
     153    private NodeEquality getCommonEqualityLevel(List<ITaskTreeNode> children1, 
     154                                                List<ITaskTreeNode> children2) 
     155    { 
     156        NodeEquality listEquality = NodeEquality.LEXICALLY_EQUAL; 
     157         
    80158        NodeEquality childEquality; 
    81159        NodeEquality currentEquality; 
    82         for (ITaskTreeNode child1 : node1.getChildren()) { 
     160        for (ITaskTreeNode child1 : children1) { 
    83161            childEquality = null; 
    84             for (ITaskTreeNode child2 : node2.getChildren()) { 
    85                 currentEquality = mRuleManager.applyRules(child1, child2); 
     162            for (ITaskTreeNode child2 : children2) { 
     163                currentEquality = callRuleManager(child1, child2, null); 
    86164                if ((currentEquality != null) && (currentEquality != NodeEquality.UNEQUAL)) { 
    87165                    if (childEquality == null) { 
     
    91169                        childEquality = childEquality.getCommonDenominator(currentEquality); 
    92170                    } 
    93                 } 
    94             } 
    95              
    96             if (childEquality != null) { 
    97                 selectionEquality = selectionEquality.getCommonDenominator(childEquality); 
    98             } 
    99             else { 
    100                 return NodeEquality.UNEQUAL; 
    101             } 
    102         } 
    103  
    104         // compare each child of selection two with each child of selection one 
    105         for (ITaskTreeNode child2 : node2.getChildren()) { 
    106             childEquality = null; 
    107             for (ITaskTreeNode child1 : node1.getChildren()) { 
    108                 currentEquality = mRuleManager.applyRules(child1, child2); 
    109                 if ((currentEquality != null) && (currentEquality != NodeEquality.UNEQUAL)) { 
    110                     if (childEquality == null) { 
    111                         childEquality = currentEquality; 
    112                     } 
    113                     else { 
    114                         childEquality = childEquality.getCommonDenominator(currentEquality); 
     171                     
     172                    if (childEquality == NodeEquality.SEMANTICALLY_EQUAL) { 
     173                        // as we calculate only the common denominator, we can break up here for 
     174                        // the current child. We will not improve the denominator anymore 
     175                        break; 
    115176                    } 
    116177                } 
    117178            } 
    118179             
    119             if (childEquality != null) { 
    120                 selectionEquality = selectionEquality.getCommonDenominator(childEquality); 
     180            if (childEquality == null) { 
     181                // we did not find any child in the second list, that is equal to the searched 
     182                // child 
     183                return NodeEquality.UNEQUAL; 
    121184            } 
    122185            else { 
    123                 return NodeEquality.UNEQUAL; 
    124             } 
    125         } 
    126  
    127         return selectionEquality; 
     186                listEquality = listEquality.getCommonDenominator(childEquality); 
     187            } 
     188        } 
     189 
     190        return listEquality; 
     191    } 
     192 
     193    /** 
     194     * <p> 
     195     * TODO: comment 
     196     * </p> 
     197     * 
     198     * @param children1 
     199     * @param children2 
     200     * @param requiredEqualityLevel 
     201     */ 
     202    private boolean checkEqualityLevel(List<ITaskTreeNode> children1, 
     203                                       List<ITaskTreeNode> children2, 
     204                                       NodeEquality        requiredEqualityLevel) 
     205    { 
     206        NodeEquality childEquality; 
     207        NodeEquality currentEquality; 
     208        for (ITaskTreeNode child1 : children1) { 
     209            childEquality = null; 
     210            for (ITaskTreeNode child2 : children2) { 
     211                currentEquality = callRuleManager(child1, child2, requiredEqualityLevel); 
     212                if ((currentEquality != null) && (currentEquality.isAtLeast(requiredEqualityLevel))) 
     213                { 
     214                    // we found at least one equal child with sufficient equality in the 
     215                    // second list. So be can break up for this child. 
     216                    childEquality = currentEquality; 
     217                    break; 
     218                } 
     219            } 
     220             
     221            if (childEquality == null) { 
     222                // we did not find any child in the second list, that is equal to the searched 
     223                // child 
     224                return false; 
     225            } 
     226        } 
     227 
     228        // for all children, we found an equality  
     229        return true; 
     230    } 
     231 
     232    /** 
     233     * <p> 
     234     * TODO: comment 
     235     * </p> 
     236     * 
     237     * @param child1 
     238     * @param child2 
     239     * @param requiredEqualityLevel 
     240     * @return 
     241     */ 
     242    private NodeEquality callRuleManager(ITaskTreeNode child1, 
     243                                         ITaskTreeNode child2, 
     244                                         NodeEquality  requiredEqualityLevel) 
     245    { 
     246        if (requiredEqualityLevel == null) { 
     247            return mRuleManager.compare(child1, child2); 
     248        } 
     249        else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) { 
     250            return requiredEqualityLevel; 
     251        } 
     252        else { 
     253            return NodeEquality.UNEQUAL; 
     254        } 
    128255    } 
    129256 
Note: See TracChangeset for help on using the changeset viewer.