ModeAssignment.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
00020  *
00021  */
00022 
00023 
00024 package dfengine;
00025 
00026 import java.util.*;
00027 
00028 import utils.*;
00029 
00030 public class ModeAssignment implements Cloneable {
00031 
00032     /*
00033      * A pair of type (Mode, ModeAssignmentDAGNode).
00034      * This is the type of values in the modes map (below).
00035      */
00036     protected class ModeNodePair {
00037 
00038         Mode mode;
00039         
00040         ModeAssignmentDAGNode node;  // only valid if maDag != null
00041         
00042         ModeNodePair(Mode m, ModeAssignmentDAGNode n) {
00043             mode = m;
00044             node = n;
00045         }
00046 
00047         public boolean equals(Object o) {
00048             if (!(o instanceof ModeNodePair)) return false;
00049             ModeNodePair other = (ModeNodePair)o;
00050             return mode.equals(other.mode);
00051         }
00052     }
00053 
00054     /*
00055      * Map from Component to ModeNodePair.
00056      */
00057     protected TreeMap modes = new TreeMap();
00058 
00059     /*
00060      * This DAG represents the dependencies between components.
00061      * Created only on demand; if it is null, then it has not yet been created.
00062      *
00063      * As soon as it is created (i.e., maDag != null), all methods have to ensure its
00064      * consistency with this MA.
00065      */
00066     protected ModeAssignmentDAG maDag = null;
00067 
00068 
00069 
00073     public ModeAssignment() {
00074     }
00075 
00076     /*
00077      * Returns the MA-DAG for this MA.
00078      *
00079      * If the MA-DAG has not yet been created, then this is done now (lazy creation).
00080      */
00081     public ModeAssignmentDAG getMaDag() {
00082         if (maDag == null) {
00083             maDag = createModeAssignmentDAG();
00084         }
00085         
00086         assert(invariant());
00087 
00088         return maDag;
00089     }
00090 
00091     public Object clone() {
00092 
00093         assert(invariant());
00094 
00095         ModeAssignment newMA = new ModeAssignment();
00096         newMA.maDag = null;
00097 
00098         Iterator itPairs = modes.values().iterator();
00099         while (itPairs.hasNext()) {
00100             ModeNodePair pair = (ModeNodePair)itPairs.next();
00101             ModeNodePair newPair = new ModeNodePair(pair.mode, null);
00102             newMA.modes.put(pair.mode.component, newPair);
00103         }
00104 
00105         assert(newMA.invariant());
00106 
00107         return newMA;
00108     }
00109 
00110     public boolean equals(Object o) {
00111 
00112         if (!(o instanceof ModeAssignment)) return false;
00113         else {
00114             ModeAssignment other = (ModeAssignment)o;
00115             return modes.equals(other.modes);            
00116         }
00117     }
00118 
00119     /*
00120      * Returns the number of modes in this MA.
00121      */
00122     public int size() {
00123         return modes.size();
00124     }
00125 
00126     /*
00127      * Returns all components in this MA.
00128      */
00129     public Set getComponents() {
00130         return modes.keySet();
00131     }
00132 
00133     /*
00134      * Returns true iff the two MAs are of equal size and contain the same components.
00135      */
00136     public boolean equalComponents(ModeAssignment other) {
00137         boolean result;
00138 
00139         if (size() == other.size()) {
00140             Set comps1 = modes.keySet();
00141             Set comps2 = other.modes.keySet();
00142             result = comps1.equals(comps2);
00143 
00144         } else result = false;
00145         
00146         assert(postcond_equalComponents(other, result));
00147         return result;
00148     }
00149 
00150     /*
00151      * For test purposes only: this is the postcondition of equalComponents().
00152      * "result" is the return value of equalComponents() which is to be checked.
00153      * Returns true iff "result" is correct.
00154      */
00155     protected boolean postcond_equalComponents(ModeAssignment other, boolean result) {
00156         
00157         boolean correctResult = true;
00158 
00159         Iterator itModes = iterator();
00160         while (itModes.hasNext()) {
00161             
00162             Mode mode = (Mode)itModes.next();
00163             Mode otherMode = other.getMode(mode.getComponent()); 
00164             if (otherMode == null) {
00165                 correctResult = false;
00166                 break;
00167             }
00168         }
00169 
00170         if (correctResult) {
00171             Iterator itOtherModes = other.iterator();
00172             while (itOtherModes.hasNext()) {
00173                 Mode otherMode = (Mode)itOtherModes.next();
00174                 Mode mode = getMode(otherMode.getComponent());
00175                 if (mode == null) {
00176                     correctResult = false;
00177                     break;
00178                 }
00179             }
00180         }
00181 
00182         return (result == correctResult);
00183     }
00184 
00185     /*
00186      * For debugging.
00187      */
00188     public String toStringShort() {
00189         StringBuffer result = new StringBuffer();
00190 
00191         Iterator itValues = modes.values().iterator();
00192         while (itValues.hasNext()) {
00193             Mode m = ((ModeNodePair)itValues.next()).mode;
00194             if (result.length() > 0) result.append("; ");
00195             result.append(m.toStringShort());
00196         }
00197 
00198         return result.toString();
00199     }
00200 
00201     /*
00202      * Substitutes certain modes.
00203      *
00204      * fromMode: one of Mode.MODE_NAB/AB/IF.
00205      * toMode: one of Mode.MODE_NAB/AB/IF
00206      *
00207      * Returns: true iff any modes have been substituted.
00208      */
00209     public boolean subst(int fromMode, int toMode) {
00210         assert((fromMode != Mode.MODE_DF) && (toMode != Mode.MODE_DF));
00211         assert(invariant());
00212         
00213         boolean result = false;
00214 
00215         Set entries = modes.entrySet();
00216         Iterator itEntries = entries.iterator();
00217         while (itEntries.hasNext()) {
00218             Map.Entry entry = (Map.Entry)itEntries.next();
00219             
00220             ModeNodePair pair = (ModeNodePair)entry.getValue();
00221             if (pair.mode.type == fromMode) {
00222                 Mode newMode = pair.mode.getComponent().getMode(toMode, null);
00223                 pair.mode = newMode;
00224                 
00225                 result = true;
00226             }
00227         }
00228         
00229         assert(invariant());
00230         return result;
00231     }
00232 
00233     /*
00234      * Sets the mode of comp to toMode. 
00235      *
00236      * comp must already exist in this mode assignment, AssertionError otherwise.
00237      * "parent" is ignored if toMode != Mode.MODE_DF.
00238      *
00239      * Returns "true".
00240      */
00241     public boolean subst(Component comp, int toMode, Component parent) {
00242         assert(modes.containsKey(comp));
00243         assert(invariant());
00244 
00245         ModeNodePair pair = (ModeNodePair)modes.get(comp);
00246         
00247         // remove edge in MA-DAG, if necessary
00248 
00249         if ((maDag != null) && (pair.mode.type == Mode.MODE_DF)) {
00250             Component oldParent = pair.mode.getParent();
00251             ModeAssignmentDAGNode oldParentNode = ((ModeNodePair)modes.get(oldParent)).node;
00252             maDag.removeEdge(oldParentNode, pair.node);
00253         }
00254 
00255         // substitute
00256 
00257         Mode newMode = comp.getMode(toMode, parent);
00258         pair.mode = newMode;
00259 
00260         // create edge in MA-DAG, if necessary
00261 
00262         if ((maDag != null) && (toMode == Mode.MODE_DF)) {
00263             ModeAssignmentDAGNode parentNode = ((ModeNodePair)modes.get(parent)).node;
00264             maDag.addEdge(parentNode, pair.node);
00265         }
00266 
00267         assert(invariant());
00268         return true;
00269     }
00270 
00271     /*
00272      * Like subst(Component, int, Component), but the component may not be in this assignment yet.
00273      */
00274     public boolean setMode(Component comp, int toMode, Component parent) {
00275         assert(invariant());
00276 
00277         Object o = modes.get(comp);
00278         
00279         if (o != null) {   // substitute; as above
00280             
00281             ModeNodePair pair = (ModeNodePair)o;
00282 
00283             if ((maDag != null) && (pair.mode.type == Mode.MODE_DF)) {
00284                 Component oldParent = pair.mode.getParent();
00285                 ModeAssignmentDAGNode oldParentNode = ((ModeNodePair)modes.get(oldParent)).node;
00286                 maDag.removeEdge(oldParentNode, pair.node);
00287             }
00288             
00289             // substitute
00290             
00291             Mode newMode = comp.getMode(toMode, parent);
00292             pair.mode = newMode;
00293             
00294             // create edge in MA-DAG, if necessary
00295             
00296             if ((maDag != null) && (toMode == Mode.MODE_DF)) {
00297                 ModeAssignmentDAGNode parentNode = ((ModeNodePair)modes.get(parent)).node;
00298                 maDag.addEdge(parentNode, pair.node);
00299             }
00300  
00301             assert(invariant());
00302             return true;
00303         }
00304 
00305         else {   // add new component
00306 
00307             ModeAssignmentDAGNode newNode = null;
00308             if (maDag != null) newNode = new ModeAssignmentDAGNode(comp);
00309             
00310             ModeNodePair pair = new ModeNodePair(comp.getMode(toMode, parent), newNode);
00311             modes.put(comp, pair);
00312             
00313             if (maDag != null) {
00314                 maDag.addNode(newNode);
00315                 if (toMode == Mode.MODE_DF) {
00316                     ModeAssignmentDAGNode parentNode = ((ModeNodePair)modes.get(parent)).node;
00317                     maDag.addEdge(parentNode, newNode);
00318                 }
00319             }
00320 
00321             assert(invariant());
00322             return false;
00323         }
00324 
00325     }  // setMode()
00326 
00327     /*
00328      * Sets the mode of all passed components to toMode.
00329      *
00330      * components is an ArrayList of Component. It is not required that a component
00331      * in this list must already be an element of this mode assignment.
00332      *
00333      * toMode must be != Mode.MODE_DF.
00334      *
00335      */
00336     public void setModes(ArrayList components, int toMode) {
00337         assert(toMode != Mode.MODE_DF);
00338 
00339         Iterator itComp = components.iterator();
00340         while (itComp.hasNext()) {
00341             Component c = (Component)itComp.next();
00342             setMode(c, toMode, null);
00343         }
00344     }
00345 
00346     /*
00347      * Returns the mode of the passed component.
00348      *
00349      * If the component is not yet in this assignment, then null is returned.
00350      */
00351     public Mode getMode(Component comp) {
00352         Object o = modes.get(comp);
00353         if (o == null) return null;
00354         else {
00355             return ((ModeNodePair)o).mode;
00356         }
00357     }
00358 
00359     public ModeAssignmentDAGNode getNode(Component comp) {
00360         assert(maDag != null);
00361 
00362         Object o = modes.get(comp);
00363         if (o == null) return null;
00364         else {
00365             return ((ModeNodePair)o).node;
00366         }
00367     }
00368 
00369     /*
00370      * Returns the mode type of the passed component.
00371      *
00372      * If the component is not in the mode assignment, then the default mode,
00373      * defined by defaultModeType, is returned.
00374      */
00375     public int getMode(Component comp, int defaultModeType) {
00376         Object o = modes.get(comp);
00377         
00378         if (o == null) return defaultModeType;
00379         else {
00380             return ((ModeNodePair)o).mode.type;
00381         }
00382     }
00383 
00384     /*
00385      * Returns the number of modes of type modeType.
00386      */
00387     protected int countNumModes(int modeType) {
00388         int result = 0;
00389         
00390         Iterator itModes = getModeIterator(modeType);
00391         while (itModes.hasNext()) {
00392             itModes.next();
00393             ++result;
00394         }
00395         
00396         return result;
00397     }
00398 
00399     /*
00400      * Returns the number of primary failed components.
00401      */
00402     public int getNumPFCs() {
00403         int result = (modes.size() - getNumSFCs());
00404         assert(result == countNumModes(Mode.MODE_AB) + countNumModes(Mode.MODE_IF));
00405         return result;
00406     }
00407 
00408     /*
00409      * Returns the number of secondary failed components.
00410      */
00411     public int getNumSFCs() {
00412         if (maDag == null) {
00413             return countNumModes(Mode.MODE_DF);
00414         } else {
00415             int result = maDag.getNumEdges();
00416             assert(result == countNumModes(Mode.MODE_DF));
00417             return result;
00418         }
00419     }
00420 
00421     public boolean hasMode(int modeType) {
00422         Collection values = modes.values();
00423         Iterator itPairs = values.iterator();
00424         
00425         while (itPairs.hasNext()) {
00426             ModeNodePair pair = (ModeNodePair)itPairs.next();
00427             if (pair.mode.getType() == modeType) return true;
00428         }
00429 
00430         return false;
00431     }
00432    
00433     /*
00434      * Returns the #IF of the longest DF chain.
00435      */
00436     public int computeLongestDFChain() {
00437         maDag = getMaDag();
00438         return maDag.computeMaxPathLen();
00439     }
00440 
00441     /*
00442      * The returned iterator iterates through all modes.
00443      */
00444     public Iterator iterator() {
00445         return new ModeIterator();
00446     }
00447 
00448     /*
00449      * Returns an iterator whose elements m are of type Mode
00450      * and m.type == modeType.
00451      */
00452     public Iterator getModeIterator(int modeType) {
00453         return new ModeIterator(modeType);
00454     }
00455 
00456     /*
00457      * Like getModeIterator(int), but multiple mode types can be specified.
00458      */
00459     public Iterator getModeIterator(SortedIntList modeTypes) {
00460         return new ModeIterator(modeTypes);
00461     }
00462 
00463     protected ModeAssignmentDAG createModeAssignmentDAG() {
00464         
00465         ModeAssignmentDAG dag = new ModeAssignmentDAG();
00466 
00467         // first iteration through modes: create nodes of DAG
00468 
00469         Iterator itPairs = modes.values().iterator();
00470         while (itPairs.hasNext()) {
00471             ModeNodePair pair = (ModeNodePair)itPairs.next();
00472             ModeAssignmentDAGNode n = new ModeAssignmentDAGNode(pair.mode.getComponent());
00473             dag.addNode(n);
00474             pair.node = n;
00475         }
00476 
00477         // second iteration: create edges
00478 
00479         itPairs = modes.values().iterator();
00480         while (itPairs.hasNext()) {
00481             ModeNodePair pair = (ModeNodePair)itPairs.next();
00482             if (pair.mode.type == Mode.MODE_DF) {
00483                 Component parentComp = pair.mode.parent;
00484                 ModeAssignmentDAGNode parentNode = ((ModeNodePair)modes.get(parentComp)).node;
00485                 dag.addEdge(parentNode, pair.node);
00486             } 
00487         }
00488 
00489         assert(correctMaDag(dag));
00490         return dag;
00491 
00492     }  // createModeAssignmentDAG()
00493 
00494     protected boolean invariant() {
00495         if ((maDag != null) && !correctMaDag(maDag)) return false;
00496 
00497         return true;
00498     }
00499 
00500     /*
00501      * For test purposes only: returns true iff "dag" is a correct MA-DAG of this MA.
00502      */
00503     protected boolean correctMaDag(ModeAssignmentDAG dag) {
00504         
00505         if (!dag.invariant()) return false;
00506 
00507         // iterate through modes, check if DAG conforms
00508 
00509         Iterator itPairs = modes.values().iterator();
00510         while (itPairs.hasNext()) {
00511             ModeNodePair pair = (ModeNodePair)itPairs.next();
00512             if (pair.node == null) return false;
00513             if (!dag.getNodes().contains(pair.node)) return false;
00514             
00515             if (pair.mode.type == Mode.MODE_DF) {
00516                 Component parentComp = pair.mode.parent;
00517                 ModeAssignmentDAGNode parentNode = ((ModeNodePair)modes.get(parentComp)).node;
00518                 if (!dag.hasEdge(parentNode, pair.node)) return false;
00519             }
00520         }
00521         
00522         // iterate through DAG, check if modes conform
00523         
00524         Iterator itNodes = dag.iterator();
00525         while (itNodes.hasNext()) {
00526             ModeAssignmentDAGNode n = (ModeAssignmentDAGNode)itNodes.next();
00527             if (!modes.containsKey(n.comp)) return false;
00528             
00529             Component parentComp = n.getFailurePred();
00530             if (parentComp != null) {
00531                 ModeNodePair pair = (ModeNodePair)modes.get(n.comp);
00532                 if ((pair.mode.type != Mode.MODE_DF) || (pair.mode.parent != parentComp)) return false;
00533             }
00534         }
00535         
00536 
00537         return true;
00538 
00539     }  // correctMaDag()
00540 
00541     /*
00542      * Returns true iff there is a component c in this MA which has an ancestor c_a
00543      * s.t. c_a is NOT an ancestor of c in the other MA.
00544      *
00545      * This method presumes that both MAs contain the same components.
00546      *
00547      * Complexity: O( (log(m))^2 * m^2) with m = #modes in this MA
00548      * [the "log(m)" stems from "other.getNode(..)"]
00549      */
00550     protected boolean hasMoreConstrainedNodeThan(ModeAssignment other, GraphMatrix transClosure,
00551                                                  GraphMatrix otherTransClosure) {
00552         assert(equalComponents(other));
00553 
00554         ModeAssignmentDAG dag = getMaDag();
00555         ModeAssignmentDAG otherDag = other.getMaDag();
00556 
00557         // iterate through nodes
00558 
00559         Iterator itNodes = dag.iterator();
00560         while (itNodes.hasNext()) {
00561             ModeAssignmentDAGNode node = (ModeAssignmentDAGNode)itNodes.next();
00562             ModeAssignmentDAGNode otherNode = other.getNode(node.comp);
00563 
00564             // iterate through ancestors of node
00565 
00566             Iterator itAnc = dag.getAncestorIterator(node, transClosure);
00567             while (itAnc.hasNext()) {
00568                 ModeAssignmentDAGNode anc = (ModeAssignmentDAGNode)itAnc.next();
00569                 assert(dag.isAncestor(anc, node, transClosure));
00570                        
00571                 ModeAssignmentDAGNode otherAnc = other.getNode(anc.comp);
00572                 if (!otherDag.isAncestor(otherAnc, otherNode, otherTransClosure)) return true;
00573             }
00574         }
00575         
00576         return false;
00577     }
00578 
00579 
00580     /*
00581      * THIS METHOD IS DEPRICATED! The algorithm is bad (complexity too high)!
00582      *
00583      * Returns -1 if this MA has a weaker order than other, -1 if it has a stricter order,
00584      * and 0 if both MAs have at least one component which is more constrained than in the
00585      * other MA.
00586      *
00587      * Complexity:  O( 2* (log(m))^2 * m^2) with m = #modes in this MA
00588      * [2 calls to hasMoreConstrainedNodeThan()]
00589      */
00590     public int compareOrderTo(ModeAssignment other, GraphMatrix transClosure,
00591                               GraphMatrix otherTransClosure) {
00592 
00593         assert(equalComponents(other));
00594 
00595         if (hasMoreConstrainedNodeThan(other, transClosure, otherTransClosure)) {
00596             
00597             if (other.hasMoreConstrainedNodeThan(this, otherTransClosure, transClosure)) {
00598                 return 0;
00599             } else return 1;
00600 
00601         } else {
00602             if (other.hasMoreConstrainedNodeThan(this, otherTransClosure, transClosure)) {
00603                 return -1;
00604             } else {
00605                 assert(false);
00606                 return 1000;                
00607             }
00608         }
00609     }
00610 
00611 
00613 
00614 
00615     protected class ModeIterator implements Iterator {
00616       
00617         protected Iterator modesIterator;
00618 
00619         protected Mode next = null;
00620 
00621         protected SortedIntList modeTypes = null;
00622 
00623         // Iterates through all modes.
00624         public ModeIterator() {
00625             modesIterator = modes.values().iterator();
00626             moveToNext();
00627         }
00628 
00629         // Iterates through modes of the specified type.
00630         public ModeIterator(int modeType) {
00631             this.modeTypes = new SortedIntList();
00632             this.modeTypes.addSorted(modeType);
00633             
00634             Collection values = modes.values();
00635             modesIterator = values.iterator();
00636 
00637             moveToNext();
00638         }        
00639   
00640         // Iterates through modes of the specified types.
00641         public ModeIterator(SortedIntList modeTypes) {
00642             this.modeTypes = modeTypes;
00643  
00644             Collection values = modes.values();
00645             modesIterator = values.iterator();
00646 
00647             moveToNext();
00648         }
00649 
00650         protected void moveToNext() {
00651             next = null;
00652 
00653             while (modesIterator.hasNext()) {
00654                 ModeNodePair pair = (ModeNodePair)modesIterator.next();
00655                 if ((modeTypes == null) || modeTypes.contains(pair.mode.getType())) {
00656                     next = pair.mode;
00657                     break;
00658                 }
00659             }
00660         }
00661 
00662         public boolean hasNext() {
00663             return (next != null);
00664         }
00665 
00666         public Object next() {
00667             Object result = next;
00668             moveToNext();
00669             return result;
00670         }
00671 
00672         public void remove() {
00673             throw new UnsupportedOperationException();
00674         }
00675 
00676     }  // nested class ModeIterator
00677 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16