DiagnosisEnvironments.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 theoremprover.*;
00029 import utils.*;
00030 
00031 
00032 
00033 public class DiagnosisEnvironments {
00034 
00035     protected DiagnosisProblem diagProblem;
00036 
00037     protected ABTheoremProver theoremProver;
00038 
00039     // map from String (the ass. name) to Assumption
00040     protected Map assumptions;
00041 
00042     protected DEGraph deGraph;
00043 
00044     protected ConflictSets conflictSets = new ConflictSets();
00045 
00046     protected RepairCandidates repairCandidates = new RepairCandidates();
00047 
00048 
00049 
00051 
00052     protected class ComputationStat {
00053 
00054         int numTPCalls = 0;           // # of actual theorem prover calls
00055         int numTPCalls_Alpha = 0;     // # of actual theorem prover calls for alpha nodes
00056         int numTPCalls_Beta = 0;      // # of actual theorem prover calls for beta nodes
00057         int numConflicting = 0;       // # of avoided TP calls because a conflicting conflict set was found
00058         int numDFChainTooLong = 0;    // # of nodes which are discarded as their longest DF chain exceeds a given value
00059         int numDescInconsistent = 0;  // # of nodes marked as "descendants inconsistent" for which no TP call is needed
00060         int numAlreadyExists = 0;     // # of nodes which are not created since their mode assignment already exists
00061         int numMinimal = 0;           // # of minimal nodes
00062         int numMinimal_Alpha = 0;     // # of minimal alpha nodes
00063         int numMinimal_Beta = 0;      // # of minimal beta nodes
00064         int numNodes = 0;             // total # of nodes
00065         int numAlphaNodes = 0;        // total # of alpha nodes
00066         int numBetaNodes = 0;         // total # of beta nodes
00067         int numImpliedByRC = 0;       // # of nodes which are not checked for consistency as they are implied by an
00068                                       // repair candidate
00069         int numDiscaredOrderPerms = 0;  // # of nodes whose consistency is not checked as there is already a DE
00070                                         // which comprises the same set of components
00071 
00072         public String toString() {
00073             String result = "";
00074 
00075             assert((numAlphaNodes + numBetaNodes == numNodes) && (numNodes == deGraph.getNumNodes()));
00076             result += "number of nodes: " + numNodes + "\n";
00077             result += "number of ALPHA nodes: " + numAlphaNodes + "\n";
00078             result += "number of BETA nodes: " + numBetaNodes + "\n";
00079             result += "\n";
00080 
00081             assert(numTPCalls_Alpha + numTPCalls_Beta == numTPCalls);
00082             result += "number of TP calls: " + stats.numTPCalls + "\n";
00083             result += "number of TP calls for ALPHA: " + stats.numTPCalls_Alpha + "\n";
00084             result += "number of TP calls for BETA: " + stats.numTPCalls_Beta + "\n";
00085             result += "\n";
00086 
00087             assert(numMinimal_Alpha + numMinimal_Beta == numMinimal);
00088             result += "number of nodes with a too long DF chain: " + numDFChainTooLong + "\n";
00089 
00090             result += "number of not required TP calls since conflicting: " + numConflicting + "\n";
00091             result += "number of \"descendant inconsistent\" nodes: " + numDescInconsistent + "\n";
00092             result += "number of nodes implied by repair candidates: " + numImpliedByRC + "\n";
00093             result += "number of discarded order permutations: " + numDiscaredOrderPerms + "\n";
00094             result += "number of already existing nodes: " + numAlreadyExists + "\n";
00095             result += "\n";
00096 
00097             result += "number of minimal nodes: " + numMinimal + "\n";
00098             result += "number of minimal ALPHA nodes: " + numMinimal_Alpha + "\n";
00099             result += "number of minimal BETA nodes: " + numMinimal_Beta + "\n";            
00100             
00101             return result;
00102         }
00103     }
00104 
00106 
00107     protected ComputationStat stats = new ComputationStat();
00108 
00109 
00110     public DiagnosisEnvironments(DiagnosisProblem diagProblem) {
00111         this.diagProblem = diagProblem;
00112     }
00113 
00114     /*
00115      * Creates the theorem prover containing the entire logical model.
00116      */
00117     protected void initTheoremProver() throws ParseError {
00118 
00119         LSentence logModel = new LSentence();
00120         logModel.addRules(diagProblem.getSD());
00121         logModel.addRules(diagProblem.getOBS());
00122         logModel.addRules(diagProblem.getSDD());
00123         
00124         theoremProver = new ABTheoremProver();
00125         theoremProver = logModel.asABPropositionalSentence(theoremProver);
00126         if (theoremProver == null) {
00127             throw new ParseError("[unknown]");
00128         } 
00129 
00130     }
00131     
00132     /*
00133      * Iterate through all components, create their modes.
00134      */
00135     protected void initComponents() {
00136         Iterator itC = diagProblem.getComponents().values().iterator();
00137 
00138         while (itC.hasNext()) {
00139             Component c = (Component)itC.next();
00140             c.initFromFDG(assumptions, diagProblem.getAssAB(), 
00141                           diagProblem.getAssNAB(), diagProblem.getAssIF(),
00142                           diagProblem.getAssDF()); 
00143         }
00144     }
00145 
00146     /*
00147      * Creates a map <String, Assumption>: maps the string identifiers from assumptions
00148      * to Assumption.
00149      */
00150     protected void createAssumptionMap() {
00151 
00152         assumptions = new TreeMap();
00153         List assList = theoremProver.getAssumptions();
00154 
00155         Iterator itAss = assList.iterator();
00156         while (itAss.hasNext()) {
00157             Assumption a = (Assumption)itAss.next();
00158             assert(a.getIdentifier() instanceof String);
00159             assumptions.put((String)a.getIdentifier(), a);
00160         }
00161 
00162     }
00163 
00164     /*
00165      * Util method for createInitialConflictSets().
00166      * Sets in ma the mode of compName to that mode which is defined by assName (e.g., "NAB").
00167      *
00168      * parentCompName is relevant only if assName denotes the DF mode. 
00169      */
00170     protected void setMode(ModeAssignment ma, SplittedAssumption sa) {
00171         Component c = (Component)diagProblem.getComponents().get(sa.compName);
00172         assert(c != null);
00173 
00174         if (sa.assName.equals(diagProblem.getAssAB())) {
00175             ma.setMode(c, Mode.MODE_AB, null);
00176         } else if (sa.assName.equals(diagProblem.getAssNAB())) {            
00177             ma.setMode(c, Mode.MODE_NAB, null);
00178         } else {
00179             assert(sa.assName.equals(diagProblem.getAssDF()));
00180 
00181             Component cp = (Component)diagProblem.getComponents().get(sa.parentCompName);
00182             assert(cp != null);
00183             ma.setMode(c, Mode.MODE_DF, cp);
00184         }
00185     }
00186 
00187     protected void createInitialConflictSets(ArrayList reiterConflictSets) {
00188         
00189         Iterator itRCS = reiterConflictSets.iterator();
00190         while (itRCS.hasNext()) {
00191             ArrayList cs = (ArrayList)itRCS.next();           
00192             Iterator itCS = cs.iterator();
00193             ConflictSet newCS = new ConflictSet();
00194 
00195             while (itCS.hasNext()) {
00196                 SplittedAssumption sa = (SplittedAssumption)itCS.next();
00197                 assert((sa.assName.equals(diagProblem.getAssAB()) || sa.assName.equals(diagProblem.getAssNAB()))
00198                        && (sa.parentCompName == null));
00199 
00200                 setMode(newCS, sa);                                
00201             }
00202 
00203             conflictSets.add(newCS);
00204         }
00205 
00206     }
00207 
00208     /*
00209      * Do some initialization before executing the main algorithm.
00210      */
00211     protected void initComputation(ArrayList reiterConflictSets) throws ParseError {
00212             
00213         // perform initializations
00214 
00215         initTheoremProver();                
00216         createAssumptionMap();
00217         initComponents();
00218         diagProblem.getFDG().computeIndirectDeps();
00219         diagProblem.getFDG().computeCommonAncestorGraph(true);
00220         createInitialConflictSets(reiterConflictSets);
00221 
00222         // debug output
00223 
00224         printComponents();
00225         //System.out.println("\nReiter conflict sets:\n");
00226         printConflictSets();
00227         /*System.out.println("\n");
00228         System.out.println("FAILURE DEPENDENCY GRAPH:\n");
00229         System.out.println(diagProblem.getFDG().toString());
00230         System.out.println("\n");*/
00231     }
00232 
00233     public RepairCandidates computeRepairCandidates(ArrayList diags, boolean computeBetaDE, 
00234                                                     int maxDFChainSize,
00235                                                     boolean discardOrderPerms,
00236                                                     ArrayList reiterConflictSets) 
00237         throws ParseError {
00238         
00239         // initialisations
00240         initComputation(reiterConflictSets);                
00241 
00242         // compute the DE Graph
00243 
00244         Date startComputationTime = new Date();
00245 
00246         deGraph = new DEGraph();
00247         if (discardOrderPerms) {
00248             computeDEGraph(diags, computeBetaDE, maxDFChainSize, false, true);
00249         } else {
00250             computeDEGraph(diags, computeBetaDE, maxDFChainSize, true, false);
00251         }
00252 
00253         Date endComputationTime = new Date();
00254         long passedTime = endComputationTime.getTime() - startComputationTime.getTime();    
00255 
00256         // debug output
00257  
00258         /*
00259         System.out.println("\nDEGraph:\n");
00260         System.out.println(deGraph.toStringShort());
00261         System.out.println("\n\n");
00262 
00263         System.out.println("\nORDER RELATIONS:\n");
00264         printOrderRelations(resultingNodes);
00265         System.out.println("\n\n");
00266 
00267         System.out.println("\nREPAIR CANDIDATES:\n");
00268         System.out.println(repairCandidates.toString());
00269         System.out.println("\n\n");
00270 
00271         System.out.println("\nAll conflict sets:\n");
00272         printConflictSets();
00273         System.out.println("\n");
00274         
00275         System.out.println("\nConsistent nodes:\n");
00276         printConsistentNodes();
00277         System.out.println("\n\n");
00278         
00279         System.out.println("\nInconsistent nodes:\n");
00280         printInconsistentNodes();
00281         System.out.println("\n\n");
00282         */
00283         
00284         System.out.println("Computation time [ms]: " + passedTime);
00285         System.out.println(stats.toString());       
00286 
00287         return repairCandidates;
00288     }
00289 
00290     /*
00291      * Returns the DEs as ArrayList of ModeAssignment. The DEs are not merged.
00292      * reiterConflictSets: ArrayList of ArrayList of Assumption.
00293      * 
00294      */
00295     public ArrayList computeDEs(ArrayList diags,  
00296                                 boolean computeBetaDE, int maxDFChainSize,
00297                                 ArrayList reiterConflictSets) 
00298         throws ParseError {
00299 
00300         // initialisations
00301         initComputation(reiterConflictSets);                
00302 
00303         // compute the DE Graph
00304 
00305         Date startComputationTime = new Date();
00306 
00307         deGraph = new DEGraph();
00308         ArrayList resultingNodes = computeDEGraph(diags, computeBetaDE, maxDFChainSize, false, false);
00309 
00310         Date endComputationTime = new Date();
00311         long passedTime = endComputationTime.getTime() - startComputationTime.getTime();        
00312 
00313         // compose result
00314 
00315         ArrayList result = new ArrayList();  // list of mode assignments
00316 
00317         Iterator itN = resultingNodes.iterator();
00318         while (itN.hasNext()) {
00319             DENode n = (DENode)itN.next();
00320             result.add(n.getModeAssignment());
00321         }
00322 
00323         // debug output
00324  
00325         /*
00326           System.out.println("\nDEGraph:\n");
00327         System.out.println(deGraph.toStringShort());
00328         System.out.println("\n\n");
00329 
00330         System.out.println("\nORDER RELATIONS:\n");
00331         printOrderRelations(resultingNodes);
00332         System.out.println("\n\n");
00333 
00334         System.out.println("\nAll conflict sets:\n");
00335         printConflictSets();
00336         System.out.println("\n");
00337         
00338         System.out.println("\nConsistent nodes:\n");
00339         printConsistentNodes();
00340         System.out.println("\n\n");
00341         
00342         System.out.println("\nInconsistent nodes:\n");
00343         printInconsistentNodes();
00344         System.out.println("\n\n");
00345         */
00346 
00347         System.out.println("Computation time [ms]: " + passedTime);
00348         System.out.println(stats.toString());
00349         
00350         return result;
00351 
00352     }  // computeDEs()
00353 
00354  
00355     // util method for condProb()
00356     protected final double getModeProb(Component c, Mode m, ModeAssignment ma) {
00357 
00358         double result;
00359 
00360         if (m.getType() == Mode.MODE_IF) return c.getProbIF();
00361         else {
00362             assert(m.getType() == Mode.MODE_DF);
00363             
00364             Component parent = m.getParent();
00365             int parentMode = ma.getMode(parent, Mode.MODE_NAB);
00366             if (parentMode == Mode.MODE_NAB) result = 0.0;
00367             else {
00368                 Map dfProbMap = c.getFDNode().getProbDF(); 
00369                 result = ((Double)dfProbMap.get(new Integer(parent.getFDNode().getID()))).doubleValue();
00370             }
00371         }
00372 
00373         //System.out.println("getModeProb(" + c.getName() + ", " + m.typeAsString(m.getType()) + "), ma = " + ma.toStringShort() + ": " + result);
00374         return result;
00375     }
00376 
00377     protected class FMProbResults {
00378         double prob_nab;
00379         double sumFMProbs;
00380     }
00381 
00382     protected FMProbResults computeProb_NAB(Component c, ModeAssignment ma) {
00383         
00384         FMProbResults result = new FMProbResults();
00385         result.prob_nab = (1.0 - c.getProbIF());
00386         result.sumFMProbs = c.getProbIF();
00387         
00388         Map dfProbMap = c.getFDNode().getProbDF(); 
00389         Collection dfmodes = c.getModesDF();
00390         Iterator itDFModes = dfmodes.iterator();
00391         while (itDFModes.hasNext()) {
00392             Mode dfm = (Mode)itDFModes.next();
00393             Component parent = dfm.getParent();
00394             if (ma.getMode(parent, Mode.MODE_NAB) != Mode.MODE_NAB) {
00395                 double edge_prob 
00396                     = ((Double)dfProbMap.get(new Integer(parent.getFDNode().getID()))).doubleValue();
00397                 
00398                 result.sumFMProbs += edge_prob;
00399                 result.prob_nab *= (1 - edge_prob);
00400             }
00401         }
00402 
00403         //System.out.println("computeProb_NAB( " + c.getName() + "), ma = " + ma.toStringShort() + ": " + result.prob_nab + "[sum: " + result.sumFMProbs + "]");
00404         return result;
00405     }
00406 
00407     public double computeProb(ModeAssignment ma) {
00408         
00409         double result = 1.0;
00410 
00411         // iterate through all components, multiply prob. of each comp. mode
00412 
00413         Map comps = diagProblem.getComponents();
00414         Iterator itComp = comps.values().iterator();
00415         while (itComp.hasNext()) {
00416             Component c = (Component)itComp.next();
00417             FMProbResults probRes = computeProb_NAB(c, ma);
00418 
00419             Mode m = ma.getMode(c);
00420             if ((m == null) || (m.getType() == Mode.MODE_NAB)) result *= probRes.prob_nab;
00421             else {
00422                 double prob_ab = 1 - probRes.prob_nab;
00423                 double mode_prob = getModeProb(c, m, ma);
00424                 result *= (prob_ab * mode_prob / probRes.sumFMProbs);
00425             }
00426             
00427         }
00428 
00429         //System.out.println("total MDE prob. of " + ma.toStringShort() + ": " + result);
00430         return result;
00431 
00432     }  // computeProb
00433 
00434     protected void printConflictSets() {
00435         Iterator itCS = conflictSets.iterator();
00436         while (itCS.hasNext()) {
00437             ConflictSet cs = (ConflictSet)itCS.next();
00438             //System.out.println(cs.toStringShort());
00439         }
00440     }
00441 
00442     /*
00443      * Add diagnoses (in which "ab" was substituted by "if") to DEGraph, but only
00444      * diagnoses d such that min. #if(d) == searchNumIF
00445      *
00446      * substDiags contains the diagnoses, while diagsMinNumIF contains Integer's
00447      * indicating the min. #if of the diagnoses.
00448      *
00449      * Returns the new nodes.
00450      */
00451     protected void addDiagsToDEGraph(ArrayList substDiags, ArrayList diagsMinNumIF,
00452                                      int searchNumIF) {
00453         
00454         for (int i = 0; i < substDiags.size(); ++i) {
00455             int diagMinNumIF = ((Integer)diagsMinNumIF.get(i)).intValue();
00456             
00457             if (diagMinNumIF == searchNumIF) {
00458                 ModeAssignment substDiag = (ModeAssignment)substDiags.get(i);
00459                 DENode newRootNode = new DENode(DENode.TYPE_ALPHA, null, 0, substDiag, new TreeSet());  
00460                 newRootNode.setMinNumIF(diagMinNumIF);
00461                     
00462                 deGraph.addRootNode(newRootNode);
00463                 deGraph.getUnexpandedAlphaNodes().add(newRootNode);
00464 
00465                 stats.numNodes++;
00466                 stats.numAlphaNodes++;
00467             
00468                 //System.out.println("add new diagnosis (#if_min = " + searchNumIF + "): " + substDiag.toStringShort());
00469             
00470             } else {
00471                 //System.out.println("omit diagnosis with #if_min = " + diagMinNumIF + ": " + ((ModeAssignment)substDiags.get(i)).toStringShort());
00472             }
00473         }
00474     }
00475     
00476     protected void generateAllBetaDescendants(DENode n, int maxDFChainSize, ArrayList des,
00477                                               boolean mergeDEs, boolean discardOrderPerms) {
00478 
00479         assert(!mergeDEs || !discardOrderPerms);  // these options contradict each other
00480         assert(!n.descInconsistent());
00481 
00482         //System.out.println("generateAllBetaDescendants()");
00483         
00484         ArrayList createdNodes = expandNode(n, DENode.TYPE_BETA);
00485         
00486        // iterate through new child nodes, add them to DEG
00487                     
00488         Iterator itCreatedNodes = createdNodes.iterator();
00489         while(itCreatedNodes.hasNext()) {
00490             
00491             // create and initialize node, but only if maxDFChainSize is not exceeded
00492             // and if this mode assignment not yet exists.
00493             
00494             DENode childNode = (DENode)itCreatedNodes.next();
00495             //System.out.println("created BETA node: " + childNode.toStringShort());
00496 
00497             if ((childNode.getDistanceToRoot() <= maxDFChainSize) 
00498                 || (childNode.getModeAssignment().computeLongestDFChain() <= maxDFChainSize)) {
00499 
00500                 if (deGraph.alreadyExists(childNode.getModeAssignment(), childNode.getRootNode()) == null) {
00501                 
00502                     // add node to DEG 
00503                 
00504                     deGraph.addChildNode(n, childNode);
00505                     stats.numNodes++;
00506                     stats.numBetaNodes++;
00507                     
00508                     // check consistency if there is no repair candidate 
00509                     // which implies childNode.ma
00510                     
00511                     ModeAssignment ma = childNode.getModeAssignment();
00512                     boolean consistencyCheckNecessary = true;
00513                     RepairCandidate rc = null;
00514                     
00515                     if (mergeDEs || discardOrderPerms) {
00516                         rc = repairCandidates.findCandidateFor(ma);
00517                         if (rc != null) 
00518                         {
00519                             if (discardOrderPerms) {
00520                                 consistencyCheckNecessary = false;
00521                                 ++stats.numDiscaredOrderPerms;
00522                             }
00523                             else if (rc.impliesOrderOf(ma))
00524                             {
00525                                 consistencyCheckNecessary = false;
00526                                 ++stats.numImpliedByRC;
00527                             }
00528                         }
00529                     }
00530 
00531                     if (consistencyCheckNecessary) {
00532                         if (checkConsistency(childNode, true)) {
00533                             childNode.setMinimal(DENode.STATUS_TRUE);
00534                             ++stats.numMinimal;
00535                             ++stats.numMinimal_Beta;
00536                             
00537                             des.add(childNode); 
00538                             if (mergeDEs) {
00539                                 if (rc == null) repairCandidates.add(ma);
00540                                 else rc.mergeWith(ma);
00541                             } else if (discardOrderPerms) {
00542                                 repairCandidates.add(ma);
00543                             }
00544                         }
00545                     }
00546                     
00547                     if (childNode.descInconsistent()) {  // descendants are inconsistent                 
00548                         //System.out.println("DONT expand (BETA): desc. inconsistent: " + childNode.toStringShort()); 
00549                     } else {
00550                         
00551                         // recursive call to generateAllBetaDescendants()
00552                         generateAllBetaDescendants(childNode, maxDFChainSize, des, mergeDEs, discardOrderPerms);
00553                     }
00554                 
00555                 } else {
00556                     //System.out.println("Node already exists: " + childNode.getModeAssignment().toStringShort());
00557                     ++stats.numAlreadyExists;
00558                 }
00559 
00560             } else {
00561                 ++stats.numDFChainTooLong;
00562             }
00563         }
00564         
00565     }  // generateAllBetaDescendants()
00566 
00567     /*
00568      * Expand all nodes n with min. #if(n) == searchNumIF
00569      * Also performs cons. checks for nodes n with #if(n) == searchNumIF. Those nodes
00570      * which are consistent are returned in "des".
00571      * 
00572      */
00573     protected void performGraphExpansions(int searchNumIF, boolean computeBetaDE, int maxDFChainSize, 
00574                                           boolean mergeDEs, boolean discardOrderPerms, 
00575                                           ArrayList des) {
00576                                  
00577         assert(!mergeDEs || !discardOrderPerms);  // these options contradict each other
00578 
00579         //System.out.println("expandDEGraph: searchNumIF = " + searchNumIF);
00580 
00581         // iterate through unexpanded nodes (note: iterator is reset after each expansion
00582         //   => loop terminates when no more nodes can be expanded
00583 
00584         Iterator itUnexpNodes = deGraph.getUnexpandedAlphaNodes().iterator();
00585         while (itUnexpNodes.hasNext()) {
00586             
00587             DENode n = (DENode)itUnexpNodes.next();
00588             assert(n.getType() == DENode.TYPE_ALPHA);
00589             
00590             // check if n should be expanded in this step
00591 
00592             if (n.getMinNumIF() <= searchNumIF) {  // yes!
00593                 
00594                 // if #if(n) == searchNumIF: check consistency if there is no repair candidate 
00595                 // which implies n.ma
00596 
00597                 assert(n.getNumIF() >= searchNumIF);
00598                 if ((n.consistent() == DENode.STATUS_UNKNOWN) && (n.getNumIF() == searchNumIF)) {
00599                         
00600                     assert(!n.descInconsistent());
00601 
00602                     ModeAssignment ma = n.getModeAssignment();
00603                     boolean consistencyCheckNecessary = true;
00604                     RepairCandidate rc = null;
00605 
00606                     if (mergeDEs || discardOrderPerms) {
00607                         rc = repairCandidates.findCandidateFor(ma);
00608                         if (rc != null) 
00609                         {
00610                             if (discardOrderPerms) {
00611                                 consistencyCheckNecessary = false;
00612                                 ++stats.numDiscaredOrderPerms;
00613                             }
00614                             else if (rc.impliesOrderOf(ma))
00615                             {
00616                                 consistencyCheckNecessary = false;
00617                                 ++stats.numImpliedByRC;
00618                             }
00619                         }
00620                     }
00621                         
00622                     if (consistencyCheckNecessary) {                        
00623                         if (checkConsistency(n, computeBetaDE)) {
00624                             n.setMinimal(DENode.STATUS_TRUE);
00625                             ++stats.numMinimal;
00626                             ++stats.numMinimal_Alpha;
00627                             
00628                             des.add(n);  
00629                             if (mergeDEs) {
00630                                 if (rc == null) repairCandidates.add(ma);
00631                                 else rc.mergeWith(ma);
00632                             } else if (discardOrderPerms) {
00633                                 repairCandidates.add(ma);
00634                             }
00635                         }
00636                     }
00637 
00638                     // generate beta nodes for n
00639 
00640                     if (!n.descInconsistent() && computeBetaDE) {
00641                         generateAllBetaDescendants(n, maxDFChainSize, des, mergeDEs, discardOrderPerms);
00642                     }
00643                 }
00644                 
00645                 if (n.descInconsistent()) {  // descendants are inconsistent
00646 
00647                     deGraph.getUnexpandedAlphaNodes().remove(n);
00648                     itUnexpNodes = deGraph.getUnexpandedAlphaNodes().iterator();
00649 
00650                     //System.out.println("DONT expand: desc. inconsistent: " + n.toStringShort());  
00651                 
00652                 } else {  // --- expand ---
00653 
00654                     //System.out.println("EXPAND (ALPHA): " + n.toStringShort());
00655                     
00656                     // expand; remove from set of unexpanded nodes
00657                     ArrayList createdNodes = expandNode(n, DENode.TYPE_ALPHA);
00658                     deGraph.getUnexpandedAlphaNodes().remove(n);
00659                     
00660                     // iterate through new child nodes, add them to DEG
00661                     
00662                     Iterator itCreatedNodes = createdNodes.iterator();
00663                     while(itCreatedNodes.hasNext()) {
00664                         
00665                         // create and initialize node, but only if maxDFChainSize is not exceeded
00666                         // and if this mode assignment not yet exists.
00667                         
00668                         DENode childNode = (DENode)itCreatedNodes.next();
00669                         if ((childNode.getDistanceToRoot() <= maxDFChainSize) 
00670                             || (childNode.getModeAssignment().computeLongestDFChain() <= maxDFChainSize)) {
00671 
00672                             if (deGraph.alreadyExists(childNode.getModeAssignment(), 
00673                                                       childNode.getRootNode()) == null) {
00674                             
00675                                 int childMinNumIF = computeMinNumIF(childNode.getModeAssignment(), maxDFChainSize);
00676                                 childNode.setMinNumIF(childMinNumIF);
00677                                 
00678                                 // add node to DEG and to unexpanded nodes
00679                                 
00680                                 deGraph.addChildNode(n, childNode);
00681                                 deGraph.getUnexpandedAlphaNodes().add(childNode);
00682                                 stats.numNodes++;
00683                                 stats.numAlphaNodes++;
00684                             } else {
00685                                 //System.out.println("Node already exists: " + childNode.getModeAssignment().toStringShort());
00686                                 ++stats.numAlreadyExists;
00687                             }
00688                             
00689                         } else {
00690                             ++stats.numDFChainTooLong;
00691                         }
00692                         
00693                     }  // iterate through new child nodes
00694                     
00695                     // reset iterator                
00696                     itUnexpNodes = deGraph.getUnexpandedAlphaNodes().iterator();
00697                     
00698                 }  // expand n
00699             
00700             }  // if (n.getMinNumIF() == searchNumIF)
00701 
00702             else {
00703                 //System.out.println("DONT expand: " + n.getModeAssignment().toStringShort());
00704             }
00705             
00706         }  // iterate through unexpanded nodes
00707         
00708     }  // expandDEGraph
00709 
00710     /*
00711      * In "consideredNodes", this method returns those nodes n in DEGraph for which 
00712      * (#IF(n) == searchNumIF) holds and whose consistency has not been checked before this method
00713      * was called.
00714      *
00715      * Furthermore, in "des" this method returns those nodes of consideredNodes which are not implied
00716      * by any repair candidate and which are consistent.
00717      * 
00718      */
00719     protected void computeConsistentDENodes(int searchNumIF, boolean computeBetaDE, int maxDFChainSize,
00720                                             boolean mergeDEs, boolean discardOrderPerms,
00721                                             ArrayList consideredNodes, ArrayList des) {
00722 
00723         assert(consideredNodes.size() == 0);
00724         assert(!mergeDEs || !discardOrderPerms);  // these options contradict each other
00725 
00726          // iterate through all nodes
00727 
00728         Iterator itNodes = deGraph.iterator();
00729         while (itNodes.hasNext()) {
00730             DENode n = (DENode)itNodes.next();
00731 
00732             // proceed only if the consistency status is unknown and the #if == searchNumIF
00733 
00734              // even new nodes may be marked as inconsistent if a predecessor node has a parent
00735             // whose conflict set refutes all descendants
00736             if ((n.consistent() == DENode.STATUS_UNKNOWN) && (n.getNumIF() == searchNumIF)) {
00737 
00738                 assert((n.getType() == DENode.TYPE_ALPHA) && !n.expanded(DENode.TYPE_BETA));
00739 
00740                 ModeAssignment ma = n.getModeAssignment();
00741                 boolean consistencyCheckNecessary = true;
00742                 RepairCandidate rc = null;
00743 
00744                 if (mergeDEs || discardOrderPerms) {
00745                     rc = repairCandidates.findCandidateFor(ma);
00746                     if (rc != null) 
00747                     {
00748                         if (discardOrderPerms) {
00749                             consistencyCheckNecessary = false;
00750                             ++stats.numDiscaredOrderPerms;
00751                         }
00752                         else if (rc.impliesOrderOf(ma)) 
00753                         {
00754                             consistencyCheckNecessary = false;
00755                             ++stats.numImpliedByRC;
00756                         }
00757                     }
00758                 }
00759 
00760                 if (consistencyCheckNecessary) {
00761 
00762                     if (checkConsistency(n, computeBetaDE)) {
00763                         n.setMinimal(DENode.STATUS_TRUE);
00764                         ++stats.numMinimal;
00765                         ++stats.numMinimal_Alpha;
00766                         
00767                         des.add(n);  
00768                         if (mergeDEs) {
00769                             if (rc == null) repairCandidates.add(ma);
00770                             else rc.mergeWith(ma);
00771                         } else if (discardOrderPerms) {
00772                             repairCandidates.add(ma);
00773                         }
00774                     }
00775                 }
00776 
00777                 consideredNodes.add(n);
00778 
00779             }
00780         }  // iterate through all nodes
00781     }  // computeConsistentDENodes()
00782 
00783     /*
00784      * This is the main algorithm. Computes all min. DEs and returns the minimal nodes in the DE Graph.
00785      */
00786     protected ArrayList computeDEGraph(ArrayList diags, boolean computeBetaDE,
00787                                        int maxDFChainSize, boolean mergeDEs, 
00788                                        boolean discardOrderPerms) {
00789 
00790         assert(!mergeDEs || !discardOrderPerms);  // these options contradict each other
00791 
00792         // ***** preparations *****
00793 
00794         // substitute "ab" in diagnoses with "if", store results in substDiags
00795         // compute min. #(if) for all diagnoses, store results in diagsMinNumIF
00796 
00797         int maxNumIF = 0;
00798 
00799         ArrayList diagsMinNumIF = new ArrayList(diags.size());
00800         ArrayList substDiags = new ArrayList(diags.size());
00801 
00802         Iterator itDiags = diags.iterator();
00803         while (itDiags.hasNext()) {
00804             ArrayList diagnosis = (ArrayList)itDiags.next();
00805             if (diagnosis.size() > maxNumIF) maxNumIF = diagnosis.size();
00806             ModeAssignment substDiag = new ModeAssignment();
00807             substDiag.setModes(diagnosis, Mode.MODE_IF);
00808             substDiags.add(substDiag);
00809             
00810             int diagMinNumIF = computeMinNumIF(substDiag, maxDFChainSize);
00811             diagsMinNumIF.add(new Integer(diagMinNumIF));
00812         }
00813 
00814         // ***** main algorithm: loop until consistent DEs with a minimal #if are found *****
00815        
00816         ArrayList des = new ArrayList();
00817         ArrayList newNodes;
00818 
00819         int searchNumIF = 1; // start with looking for DEs with #if == 1
00820         do {            
00821         
00822             //System.out.println("searchNumIf = " + searchNumIF);
00823     
00824             // iterate through diagnoses; for each d with #if(d) == searchNumIF: add d to DEG
00825             addDiagsToDEGraph(substDiags, diagsMinNumIF, searchNumIF);
00826 
00827             //System.out.println("look for consistent nodes BEFORE expansion");
00828             ArrayList nodesForBetaExpansion = new ArrayList();
00829             computeConsistentDENodes(searchNumIF, computeBetaDE, maxDFChainSize, mergeDEs,
00830                                      discardOrderPerms, nodesForBetaExpansion, des);
00831             if (computeBetaDE) {
00832                 performBetaExpansions(nodesForBetaExpansion, maxDFChainSize, des, mergeDEs,
00833                                       discardOrderPerms);
00834             }
00835             performGraphExpansions(searchNumIF, computeBetaDE, maxDFChainSize, mergeDEs, 
00836                                    discardOrderPerms, des);
00837         
00838             // can we terminate?
00839             
00840             if (des.size() > 0) return des;
00841             else ++searchNumIF;            
00842 
00843         } while (searchNumIF <= maxNumIF); 
00844 
00845         return des;
00846 
00847     }  // computeDEGraph()
00848 
00849     protected void performBetaExpansions(ArrayList nodesToExpand, int maxDFChainSize, ArrayList des,
00850                                          boolean mergeDEs, boolean discardOrderPerms) {
00851 
00852         Iterator itNodes = nodesToExpand.iterator();
00853         while (itNodes.hasNext()) {
00854             DENode n = (DENode)itNodes.next();
00855             if (!n.descInconsistent()) {
00856                 generateAllBetaDescendants(n, maxDFChainSize, des, mergeDEs, discardOrderPerms);
00857             }
00858         }
00859     }
00860     
00861     protected void printOrderRelations(ArrayList nodes) {
00862 
00863         int n = nodes.size();
00864         for (int i = 0; i < n; ++i) {
00865             for (int j = i + 1; j < n; ++j) {
00866                 
00867                 DENode node_i = (DENode)nodes.get(i);
00868                 DENode node_j = (DENode)nodes.get(j);
00869                 
00870                 if (node_i.getNumIF() == node_j.getNumIF()) {
00871                     ModeAssignment ma_i = node_i.getModeAssignment();
00872                     ModeAssignment ma_j = node_j.getModeAssignment();
00873 
00874                     if (ma_i.equalComponents(ma_j)) {
00875 
00876                         GraphMatrix tc_i = ma_i.getMaDag().computeTransitiveClosure(false);
00877                         GraphMatrix tc_j = ma_j.getMaDag().computeTransitiveClosure(false);
00878 
00879                         int order = ma_i.compareOrderTo(ma_j, tc_i, tc_j);
00880                         if (order == -1) {
00881                             System.out.println("WEAKER: " + node_i.getID() + " than " + node_j.getID());
00882                         } else if (order == 1) {
00883                             System.out.println("STRONGER: " + node_i.getID() + " than " + node_j.getID());
00884                         } else {
00885                             assert(order == 0);
00886 
00887                             System.out.println("INDEFINITE: " + node_i.getID() + ", " + node_j.getID());
00888                         }
00889                         
00890                         
00891                     }
00892                 }
00893                 
00894             }
00895         }
00896     }
00897     
00898 
00899     /*
00900      * Performs call to TP, returns "null" if consistent, otherwise the
00901      * conflict set is returned.
00902      */
00903     protected ArrayList callTheoremProver(ModeAssignment ma) {
00904      
00905         TreeMap components = diagProblem.getComponents();
00906         Iterator itC = components.values().iterator();
00907         ArrayList posAssumptions = new ArrayList();
00908         ArrayList negAssumptions = new ArrayList();
00909 
00910         // iterate through all comp.; determine pos. and neg. assumptions based on ma
00911 
00912         while (itC.hasNext()) {
00913             Component c = (Component)itC.next();
00914             Mode m = ma.getMode(c);
00915             if (m == null) m = c.getModeNAB();
00916             
00917             if (m.getType() == Mode.MODE_NAB) {
00918                 Assumption a = c.getModeNAB().getAssumption();
00919                 if (a != null) posAssumptions.add(a);
00920                 
00921                 a = c.getModeAB().getAssumption();
00922                 if (a != null) negAssumptions.add(a);
00923 
00924                 a = c.getModeIF().getAssumption();
00925                 if (a != null) negAssumptions.add(a);
00926 
00927                 Collection dfModes = c.getModesDF();
00928                 Iterator itDFModes = dfModes.iterator();
00929                 while (itDFModes.hasNext()) {
00930                     Mode dfm = (Mode)itDFModes.next();
00931                     a = dfm.getAssumption();
00932                     if (a != null) negAssumptions.add(a);
00933                 }
00934 
00935             } else if (m.getType() == Mode.MODE_IF) {
00936 
00937                 Assumption a = c.getModeNAB().getAssumption();
00938                 if (a != null) negAssumptions.add(a);
00939 
00940                 a = c.getModeAB().getAssumption();
00941                 if (a != null) posAssumptions.add(a);
00942 
00943                 a = c.getModeIF().getAssumption();
00944                 if (a != null) posAssumptions.add(a);
00945 
00946                 Collection dfModes = c.getModesDF();
00947                 Iterator itDFModes = dfModes.iterator();
00948                 while (itDFModes.hasNext()) {
00949                     Mode dfm = (Mode)itDFModes.next();
00950                     a = dfm.getAssumption();
00951                     if (a != null) negAssumptions.add(a);
00952                 }
00953             
00954             } else {  // DF
00955 
00956                 assert(m.getType() == Mode.MODE_DF);
00957 
00958                 Assumption a = c.getModeNAB().getAssumption();
00959                 if (a != null) negAssumptions.add(a);
00960 
00961                 a = c.getModeAB().getAssumption();
00962                 if (a != null) posAssumptions.add(a);
00963 
00964                 a = c.getModeIF().getAssumption();
00965                 if (a != null) negAssumptions.add(a);
00966 
00967                 Collection dfModes = c.getModesDF();
00968                 Iterator itDFModes = dfModes.iterator();
00969                 while (itDFModes.hasNext()) {
00970                     Mode dfm = (Mode)itDFModes.next();
00971                     a = dfm.getAssumption();
00972                     if (a != null) {
00973                         if (dfm.getParent() == m.getParent()) posAssumptions.add(a);
00974                         else negAssumptions.add(a);
00975                     }
00976                 }
00977             }
00978             
00979         }  // iterate through all components
00980 
00981         // make call to theorem prover
00982         
00983         boolean consistent = theoremProver.checkConsistency(posAssumptions, negAssumptions);
00984         if (consistent) return null;
00985         else return theoremProver.getConflictSet();
00986 
00987     } // callTheoremProver()
00988 
00989     /*
00990      * Adds a new conflict set which is defined by a list of Assumption's.
00991      *
00992      * Return the converted conflict set.
00993      */
00994     protected ConflictSet addConflictSet(ArrayList assumptions) {
00995 
00996         ConflictSet cs = new ConflictSet();
00997 
00998         Iterator itAss = assumptions.iterator();
00999         while (itAss.hasNext()) {
01000             Assumption a = (Assumption)itAss.next();
01001             SplittedAssumption sa = diagProblem.splitAssumption(a);
01002             setMode(cs, sa);            
01003         }
01004 
01005         conflictSets.add(cs);
01006         return cs;
01007     }
01008 
01009     /*
01010      * Util method for conflictsWithDescendants().
01011      *
01012      * Returns true iff at least one of the components represented by itPossDesc
01013      * depend in the FDG (directly or indirectly) on c.
01014      *
01015      * It is asserted that the modes in itPossDesc are IF-modes. Moreover, such a mode is only
01016      * considered if it NOT in constCompModes!! 
01017      */
01018     protected boolean existsDependentComp(Component c, Iterator itPossDesc, TreeSet constCompModes) {
01019         boolean result = false;
01020 
01021         while (itPossDesc.hasNext()) {
01022             Mode depM = (Mode)itPossDesc.next();
01023             assert(depM.getType() == Mode.MODE_IF);
01024 
01025             if (!constCompModes.contains(depM) 
01026                 && diagProblem.getFDG().hasIndirectDependency(c, depM.getComponent())) {
01027                 
01028                 result = true;
01029                 break;
01030             }
01031         }
01032         
01033         //System.out.println("existsDependentComp(): " + result);
01034         return result;
01035     }
01036 
01037     /*
01038      * Returns true iff one of the components in itPossAnc is an ancestor of c.
01039      */
01040     protected boolean existsAncestor(Component c, Iterator itPossAnc) {
01041         boolean result = false;
01042 
01043         while (itPossAnc.hasNext()) {
01044             Mode ancM = (Mode)itPossAnc.next();
01045             if (diagProblem.getFDG().hasIndirectDependency(ancM.getComponent(), c)) {
01046                 result = true;
01047                 break;
01048             }
01049         }
01050         
01051         //System.out.println("existsAncestor(): " + result);
01052         return result;
01053     }
01054     
01055     /*
01056      * Like existsDependentComp(), but this method checks if c and one of the IF-comp. in itModes
01057      * have an common ancestor.
01058      */
01059     protected boolean existsCommonAncestor(Component c, Iterator itIFModes, TreeSet constCompModes) {
01060         boolean result = false;
01061    
01062         while (itIFModes.hasNext()) {
01063             Mode ifMode = (Mode)itIFModes.next();
01064             assert(ifMode.getType() == Mode.MODE_IF);
01065 
01066             if (!constCompModes.contains(ifMode)
01067                 && diagProblem.getFDG().haveCommonAncestor(ifMode.getComponent(), c)) {
01068 
01069                 result = true;
01070                 break;
01071             }
01072         }
01073         
01074         //System.out.println("existsCommonAncestor(): " + result);
01075         return result;
01076     }
01077 
01078     /*
01079      * Returns true if cs proves that all descendants of n must be inconsistent.
01080      */
01081     protected boolean conflictsWithDescendants(ConflictSet cs, DENode n, boolean computeBetaDE) {
01082      
01083         //System.out.println("check conflictsWithDescendants(): cs = " + cs.toStringShort() + " --- " + n.toStringShort());
01084 
01085         // constMA is those part of n.ma which remains constant in all descendants;
01086         // in the current implementation: constMA = n.ma
01087         ModeAssignment constMA = n.getModeAssignment();  
01088         //System.out.println("Constant MA: " + constMA.toStringShort());
01089 
01090         // iterate through conflict set modes, determine if cs refutes n and its descendants
01091 
01092         boolean result = true;  // result is true per default, try to find reason why not all descendants are refuted
01093 
01094         Iterator itCS = cs.iterator();
01095         while (itCS.hasNext()) {
01096             Mode csMode = (Mode)itCS.next();
01097             //System.out.println("csMode: " + csMode.toStringShort());
01098             Component csComp = csMode.getComponent();
01099             
01100             Mode constMode = constMA.getMode(csComp);
01101             
01102             // check if csComp, the component in the conflict set, is in constMA
01103 
01104             if (constMode != null) {  // yes!
01105                 
01106                 //System.out.println("csComp is in constMA, constMode: " + constMode.toStringShort());
01107 
01108                 // result is false if the modes are different in cs and constMa 
01109                 // AND if it is not the case that csComp is IF in cs and DF in constMA
01110 
01111                 if (! ( (constMode == csMode) 
01112                         || ((csMode.getType() == Mode.MODE_IF) 
01113                             && (constMode.getType() == Mode.MODE_DF)) )
01114                     ) {
01115                     
01116                     assert(false);  // because I think this case cannot occur (?)
01117                     //System.out.println("No conflict: csComp has different modes in cs and constMA");
01118                     result = false;
01119                     break;
01120                 }
01121 
01122             } else {  // no: csComp is not in constMA
01123 
01124                 //System.out.println("csComp is not in constMA");
01125 
01126                 // check if csComp is NAB in both cs and n.ma
01127 
01128                 if ((csMode.getType() == Mode.MODE_NAB) 
01129                     && (n.getModeAssignment().getMode(csComp) == null)) {  // yes!
01130                     
01131                     //System.out.println("But csComp is NAB in both cs and n.ma");
01132 
01133                     // ----- determine: is NAB(csComp) constant in all descendants of n??  -----
01134 
01135                     boolean constNAB = true;
01136 
01137                     // if computeBetaDE: is there any FDG-ancestor of csComp in n.ma?
01138                     if (computeBetaDE && existsAncestor(csComp, n.getModeAssignment().iterator())) {
01139                         //System.out.println("No conflict: computeBetaDE, and there is an ancestor of csComp");
01140                         constNAB = false;
01141                     }
01142 
01143                     // only for ALPHA nodes:
01144 
01145                     if (constNAB && (n.getType() == DENode.TYPE_ALPHA)) {
01146    
01147                         // is csComp a FDG-ancestor of any IF-component?
01148                         if (existsDependentComp(csComp, 
01149                                                 n.getModeAssignment().getModeIterator(Mode.MODE_IF),
01150                                                 n.getConstCompModes())) {
01151                             
01152                             //System.out.println("No conflict: there is an IF-component which depends on csComp");
01153                             constNAB = false;
01154                         }
01155                         
01156                         // if computeBetaDE: have csComp and any IF-component a common ancestor?
01157                         if (constNAB  && computeBetaDE
01158                             &&  existsCommonAncestor(csComp, n.getModeAssignment().getModeIterator(Mode.MODE_IF),
01159                                                      n.getConstCompModes())) {
01160 
01161                             //System.out.println("No conflict: computeBetaDE, and csComp has a common ancestor " + "with an IF-component");
01162                             constNAB = false;
01163                         }                                                             
01164                         
01165                     }                    
01166 
01167                     //System.out.println("constNAB(" + csComp.getName() + "): " + constNAB);
01168 
01169                     if (!constNAB) {
01170                         result = false;
01171                         break;
01172                     }
01173 
01174                 } else {  // no, csComp is IF or DF in cs and/or n.ma (and csComp is not in constMA)
01175                     //System.out.println("csComp is != NAB either in cs or in n.ma");
01176                     result = false;
01177                     break;
01178                 }
01179                 
01180             }
01181         }
01182 
01183         //System.out.println("conflictsWithDescendants: RESULT = " + result);
01184         return result;
01185 
01186     }  // conflictsWithDescendants()
01187 
01188     /*
01189      * Looks for a conflict set which conflicts with n.ma.
01190      *
01191      * Returns null if no such CS is found.
01192      */
01193     protected ConflictSet searchConflictForNode(DENode n) {
01194         
01195         // first: check if conflict set p.cs of parent p refutes n.ma
01196 
01197         if (n.hasParents()) {
01198             Iterator itParents = n.getParentsIterator();
01199             if (itParents.hasNext()) {
01200                 DENode parent = (DENode)itParents.next();
01201                 assert(!itParents.hasNext()); // only 1 parent possible!
01202                 ConflictSet cs = parent.getConflictSet();
01203                 if ((cs != null) && cs.conflictsWith(n.getModeAssignment())) {
01204                     //System.out.println("parent conflict set refutes child");
01205                     return cs;
01206                 }
01207             }
01208         }
01209 
01210         // if not: search through all conflict sets
01211 
01212         return conflictSets.conflictsWith(n.getModeAssignment());
01213     }
01214 
01215     /*
01216      * Returns if the MA of n is consistent.
01217      *
01218      * First checks if n.ma is in conflict with a previously computed conflict set.
01219      * If not, make a call to the TP.
01220      */
01221     protected boolean checkConsistency(DENode n, boolean computeBetaDE) {
01222 
01223         assert(!n.descInconsistent() && (n.consistent() == DENode.STATUS_UNKNOWN));
01224 
01225         boolean result;
01226 
01227         if (!n.hasParents()) {  // root node: n.ma is a minimal diagnosis => consistent!
01228             n.setConsistent(DENode.STATUS_TRUE);            
01229             //System.out.println("root node must be consistent: " + n.toStringShort());
01230             result = true;  
01231         }
01232         
01233         else {  // no root node and the descInconsistent flag is not set
01234 
01235             ModeAssignment ma = n.getModeAssignment();
01236         
01237             // check if there is a conflict set refuting n.ma
01238             
01239             ConflictSet cs = searchConflictForNode(n);
01240             if (cs != null) {  // CS found
01241                 assert(callTheoremProver(ma) != null);
01242                 
01243                 n.setConsistent(DENode.STATUS_FALSE);
01244                 n.setConflictSet(cs);
01245                 stats.numConflicting++;
01246 
01247                 //System.out.println("existing conflict set refutes MA; ma: " + ma.toStringShort() + ";  cs: " + cs.toStringShort());
01248 
01249                 // does CS also refute the descendants?
01250 
01251                 if (conflictsWithDescendants(cs, n, computeBetaDE)) {
01252                     deGraph.propagateInconsToDesc(n);
01253                     ++stats.numDescInconsistent;
01254                 }
01255 
01256                 result = false;
01257             }
01258         
01259             else {  // no CS found -> TP call required
01260 
01261                 ArrayList newCS = callTheoremProver(ma);
01262                 boolean consistent = (newCS == null);
01263 
01264                 stats.numTPCalls++;
01265                 if (n.getType() == DENode.TYPE_ALPHA) stats.numTPCalls_Alpha++;
01266                 else stats.numTPCalls_Beta++; 
01267 
01268                 //System.out.println("theorem prover checks consistency: " + ma.toStringShort() + ": " + consistent);
01269 
01270                 if (consistent) {
01271                     n.setConsistent(DENode.STATUS_TRUE);
01272                     result = true;
01273                 }
01274                 else {
01275 
01276                     // store new conflict set ; determine if the new CS also refultes descendants;                    
01277 
01278                     n.setConsistent(DENode.STATUS_FALSE);
01279                     cs = addConflictSet(newCS);
01280                     n.setConflictSet(cs);
01281                     if (conflictsWithDescendants(cs, n, computeBetaDE)) {
01282                         deGraph.propagateInconsToDesc(n);
01283                         ++stats.numDescInconsistent; 
01284                     }
01285                     result = false;
01286                 }
01287             }
01288         }
01289 
01290         if (((n.getType() == DENode.TYPE_ALPHA) && n.expanded(DENode.TYPE_ALPHA))  
01291             || ((n.getType() == DENode.TYPE_BETA) && n.expanded(DENode.TYPE_BETA))) {
01292 
01293             n.releaseConstCompModes();
01294         }
01295         return result;
01296 
01297     }  // checkConsistency()
01298 
01299     protected ArrayList expandNodeAlpha(DENode n) {
01300 
01301         ArrayList result = new ArrayList();
01302         TreeSet ccm = null;
01303         
01304         // iterate through IF components in n.ma
01305         
01306         Iterator itMA = n.getModeAssignment().getModeIterator(Mode.MODE_IF);
01307         while (itMA.hasNext()) {  
01308             Mode m = (Mode)itMA.next();
01309             assert(m.getType() == Mode.MODE_IF);
01310             Component c = m.getComponent();
01311  
01312             if (c.getFDNode().hasParents()) {
01313 
01314                 if (ccm == null) {
01315                     ccm = (TreeSet)n.getConstCompModes().clone();
01316                 }
01317                 
01318                 // determine if this IF is constant 
01319                 if (!ccm.contains(m)) {  // not constant -> proceed
01320                     
01321                     // iterate through parents of c (in FDG)
01322                     
01323                     Iterator itParents = c.getFDNode().getParentsIterator();
01324                     while (itParents.hasNext()) {
01325                         FailureDepNode parFDNode = (FailureDepNode)itParents.next();
01326                         Component c_i = parFDNode.getComponent();
01327                         
01328                         // create mode assignment of new ALPHA node
01329                         
01330                         ModeAssignment newMA = (ModeAssignment)n.getModeAssignment().clone();
01331                         
01332                         if (newMA.getMode(c_i, Mode.MODE_NAB) == Mode.MODE_NAB) {
01333                             newMA.setMode(c_i, Mode.MODE_IF, null);
01334                         }
01335                         newMA.subst(c, Mode.MODE_DF, c_i);
01336                         
01337                         // create new ALPHA node
01338                         
01339                         TreeSet newCCM = (TreeSet)ccm.clone();
01340                         DENode newNode = new DENode(DENode.TYPE_ALPHA, n.getRootNode(), 
01341                                                     n.getDistanceToRoot() + 1, newMA, newCCM);
01342                         result.add(newNode);
01343                     }
01344                     
01345                     ccm.add(m);
01346 
01347                 }  // if (!ccm.contains(m))
01348             }  //  if (c.getFDNode().hasParents())
01349 
01350         }  // iterate through IF components in n.ma
01351 
01352         return result;
01353 
01354     }  // expandNodeAlpha
01355 
01356     protected ArrayList expandNodeBeta(DENode n) {
01357         
01358         ArrayList result = new ArrayList();
01359         TreeSet ccm = null;
01360         
01361         // iterate through IF/DF components c
01362         
01363         Iterator itMA = n.getModeAssignment().iterator();
01364         while(itMA.hasNext()) {
01365             
01366             Mode m = (Mode)itMA.next();
01367             assert((m.getType() == Mode.MODE_IF) || (m.getType() == Mode.MODE_DF));
01368             Component c = m.getComponent();
01369    
01370             // iterate through FDG children c_i of c
01371             
01372             Iterator itChildren = c.getFDNode().getChildrenIterator();
01373             while (itChildren.hasNext()) {
01374                 FailureDepNode childFDNode = (FailureDepNode)itChildren.next();
01375                 Component c_i = childFDNode.getComponent();
01376                 
01377                 // if FDG child is NAB -> proceed; otherwise: continue with next child
01378 
01379                 int modeType_c_i = n.getModeAssignment().getMode(c_i, Mode.MODE_NAB);
01380                 if (modeType_c_i == Mode.MODE_NAB) {
01381 
01382                     if (ccm == null) {
01383                         if (n.getType() == DENode.TYPE_BETA) {
01384                             ccm = (TreeSet)n.getConstCompModes().clone();
01385                         }
01386                         else {
01387                             ccm = new TreeSet();
01388                         }
01389                     }
01390 
01391                     // check if "df(c, c_i)" is in ccm, if no: proceed
01392 
01393                     Mode mode_df_c_i = c_i.getMode(Mode.MODE_DF, c);
01394                     if (!ccm.contains(mode_df_c_i)) {
01395                         
01396                         // create new mode assignment and new CCM; create new DENode
01397                         
01398                         ModeAssignment newMA = (ModeAssignment)n.getModeAssignment().clone();
01399                         newMA.setMode(c_i, Mode.MODE_DF, c);
01400                         TreeSet newCCM = (TreeSet)ccm.clone();
01401                         DENode newNode = new DENode(DENode.TYPE_BETA, n.getRootNode(), 
01402                                                     n.getDistanceToRoot() + 1, newMA, newCCM);
01403                         newNode.setMinNumIF(n.getMinNumIF());
01404                         result.add(newNode);
01405                         ccm.add(mode_df_c_i);
01406                     }
01407   
01408                 }  // FDG child is NAB
01409                 
01410             }  // iterate through FDG children c_i of c 
01411 
01412         }  // iterate through IF/DF modes in MA for BETA expansion
01413 
01414         return result;
01415 
01416     }  // expandNodeBeta()
01417 
01418 
01419     protected ArrayList expandNode(DENode n, int type) {
01420 
01421         ArrayList result;
01422 
01423         if (type == DENode.TYPE_ALPHA) 
01424         {
01425             assert((n.getType() == DENode.TYPE_ALPHA) && !n.expanded(DENode.TYPE_ALPHA));
01426             result = expandNodeAlpha(n);
01427             n.setExpanded(DENode.TYPE_ALPHA);
01428         } else {
01429             assert(!n.expanded(DENode.TYPE_BETA));
01430             result = expandNodeBeta(n);
01431             n.setExpanded(DENode.TYPE_BETA);
01432         }
01433 
01434         // note: const.comp.modes are required by checkConsistency()
01435         // => they can be released only after checking the consistency
01436         if ((n.consistent() != DENode.STATUS_UNKNOWN) 
01437             && (((n.getType() == DENode.TYPE_ALPHA) && n.expanded(DENode.TYPE_ALPHA))
01438                 || ((n.getType() == DENode.TYPE_BETA) && n.expanded(DENode.TYPE_BETA)))) {
01439 
01440             n.releaseConstCompModes();  
01441         }
01442         
01443         return result;
01444     }
01445 
01446     protected int computeMinNumIF(ModeAssignment ma, int maxDFChainSize) {
01447         
01448         LinkedList ifComps = new LinkedList();
01449         
01450         Iterator itIF = ma.getModeIterator(Mode.MODE_IF);
01451         while (itIF.hasNext()) {
01452             Mode m = (Mode)itIF.next();
01453             ifComps.add(m.getComponent());
01454         }
01455 
01456         ArrayList transPiPartitions = diagProblem.getFDG().computeTransPiPartitions(ifComps, maxDFChainSize);
01457         int minNumIF = transPiPartitions.size();
01458 
01459         /*
01460           System.out.print("minNumIF of MA " + n.getModeAssignment().toStringShort() + ": " + minNumIF);
01461           System.out.print(";  PI_r: ");
01462           for (int i = 0; i < transPiPartitions.size(); ++i) {
01463           ArrayList part = (ArrayList)transPiPartitions.get(i);
01464           for (int j = 0; j < part.size(); ++j) {
01465           Component c = (Component)part.get(j);
01466           System.out.print(c.getName());
01467           if (j < part.size() - 1) System.out.print(",");
01468           }
01469           if (i < transPiPartitions.size() - 1) System.out.print("; ");
01470           }
01471           System.out.println();
01472         */
01473 
01474         return minNumIF;
01475     }
01476     
01477     protected void printComponents() {
01478         Iterator itC = diagProblem.getComponents().values().iterator();
01479         while (itC.hasNext()) {
01480             Component c = (Component)itC.next();
01481             System.out.println("\n");
01482             System.out.println(c.toString());
01483         }
01484     }
01485 
01486     protected void printConsistentNodes() {
01487         Iterator itN = deGraph.iterator();
01488         while (itN.hasNext()) {
01489             DENode n = (DENode)itN.next();
01490             if (n.consistent() == DENode.STATUS_TRUE) {
01491                 System.out.println(n.toStringShort());
01492             }
01493         }
01494     }
01495 
01496     protected void printInconsistentNodes() {
01497         Iterator itN = deGraph.iterator();
01498         while (itN.hasNext()) {
01499             DENode n = (DENode)itN.next();
01500             if (n.consistent() == DENode.STATUS_FALSE) {
01501                 System.out.println(n.toStringShort());
01502             }
01503         }
01504     }
01505 
01506 
01507 }


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