00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
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     
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;           
00055         int numTPCalls_Alpha = 0;     
00056         int numTPCalls_Beta = 0;      
00057         int numConflicting = 0;       
00058         int numDFChainTooLong = 0;    
00059         int numDescInconsistent = 0;  
00060         int numAlreadyExists = 0;     
00061         int numMinimal = 0;           
00062         int numMinimal_Alpha = 0;     
00063         int numMinimal_Beta = 0;      
00064         int numNodes = 0;             
00065         int numAlphaNodes = 0;        
00066         int numBetaNodes = 0;         
00067         int numImpliedByRC = 0;       
00068                                       
00069         int numDiscaredOrderPerms = 0;  
00070                                         
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 
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 
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 
00148 
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 
00166 
00167 
00168 
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 
00210 
00211     protected void initComputation(ArrayList reiterConflictSets) throws ParseError {
00212             
00213         
00214 
00215         initTheoremProver();                
00216         createAssumptionMap();
00217         initComponents();
00218         diagProblem.getFDG().computeIndirectDeps();
00219         diagProblem.getFDG().computeCommonAncestorGraph(true);
00220         createInitialConflictSets(reiterConflictSets);
00221 
00222         
00223 
00224         printComponents();
00225         
00226         printConflictSets();
00227         
00228 
00229 
00230 
00231     }
00232 
00233     public RepairCandidates computeRepairCandidates(ArrayList diags, boolean computeBetaDE, 
00234                                                     int maxDFChainSize,
00235                                                     boolean discardOrderPerms,
00236                                                     ArrayList reiterConflictSets) 
00237         throws ParseError {
00238         
00239         
00240         initComputation(reiterConflictSets);                
00241 
00242         
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         
00257  
00258         
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283         
00284         System.out.println("Computation time [ms]: " + passedTime);
00285         System.out.println(stats.toString());       
00286 
00287         return repairCandidates;
00288     }
00289 
00290     
00291 
00292 
00293 
00294 
00295     public ArrayList computeDEs(ArrayList diags,  
00296                                 boolean computeBetaDE, int maxDFChainSize,
00297                                 ArrayList reiterConflictSets) 
00298         throws ParseError {
00299 
00300         
00301         initComputation(reiterConflictSets);                
00302 
00303         
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         
00314 
00315         ArrayList result = new ArrayList();  
00316 
00317         Iterator itN = resultingNodes.iterator();
00318         while (itN.hasNext()) {
00319             DENode n = (DENode)itN.next();
00320             result.add(n.getModeAssignment());
00321         }
00322 
00323         
00324  
00325         
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347         System.out.println("Computation time [ms]: " + passedTime);
00348         System.out.println(stats.toString());
00349         
00350         return result;
00351 
00352     }  
00353 
00354  
00355     
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         
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         
00404         return result;
00405     }
00406 
00407     public double computeProb(ModeAssignment ma) {
00408         
00409         double result = 1.0;
00410 
00411         
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         
00430         return result;
00431 
00432     }  
00433 
00434     protected void printConflictSets() {
00435         Iterator itCS = conflictSets.iterator();
00436         while (itCS.hasNext()) {
00437             ConflictSet cs = (ConflictSet)itCS.next();
00438             
00439         }
00440     }
00441 
00442     
00443 
00444 
00445 
00446 
00447 
00448 
00449 
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                 
00469             
00470             } else {
00471                 
00472             }
00473         }
00474     }
00475     
00476     protected void generateAllBetaDescendants(DENode n, int maxDFChainSize, ArrayList des,
00477                                               boolean mergeDEs, boolean discardOrderPerms) {
00478 
00479         assert(!mergeDEs || !discardOrderPerms);  
00480         assert(!n.descInconsistent());
00481 
00482         
00483         
00484         ArrayList createdNodes = expandNode(n, DENode.TYPE_BETA);
00485         
00486        
00487                     
00488         Iterator itCreatedNodes = createdNodes.iterator();
00489         while(itCreatedNodes.hasNext()) {
00490             
00491             
00492             
00493             
00494             DENode childNode = (DENode)itCreatedNodes.next();
00495             
00496 
00497             if ((childNode.getDistanceToRoot() <= maxDFChainSize) 
00498                 || (childNode.getModeAssignment().computeLongestDFChain() <= maxDFChainSize)) {
00499 
00500                 if (deGraph.alreadyExists(childNode.getModeAssignment(), childNode.getRootNode()) == null) {
00501                 
00502                     
00503                 
00504                     deGraph.addChildNode(n, childNode);
00505                     stats.numNodes++;
00506                     stats.numBetaNodes++;
00507                     
00508                     
00509                     
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()) {  
00548                         
00549                     } else {
00550                         
00551                         
00552                         generateAllBetaDescendants(childNode, maxDFChainSize, des, mergeDEs, discardOrderPerms);
00553                     }
00554                 
00555                 } else {
00556                     
00557                     ++stats.numAlreadyExists;
00558                 }
00559 
00560             } else {
00561                 ++stats.numDFChainTooLong;
00562             }
00563         }
00564         
00565     }  
00566 
00567     
00568 
00569 
00570 
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);  
00578 
00579         
00580 
00581         
00582         
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             
00591 
00592             if (n.getMinNumIF() <= searchNumIF) {  
00593                 
00594                 
00595                 
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                     
00639 
00640                     if (!n.descInconsistent() && computeBetaDE) {
00641                         generateAllBetaDescendants(n, maxDFChainSize, des, mergeDEs, discardOrderPerms);
00642                     }
00643                 }
00644                 
00645                 if (n.descInconsistent()) {  
00646 
00647                     deGraph.getUnexpandedAlphaNodes().remove(n);
00648                     itUnexpNodes = deGraph.getUnexpandedAlphaNodes().iterator();
00649 
00650                     
00651                 
00652                 } else {  
00653 
00654                     
00655                     
00656                     
00657                     ArrayList createdNodes = expandNode(n, DENode.TYPE_ALPHA);
00658                     deGraph.getUnexpandedAlphaNodes().remove(n);
00659                     
00660                     
00661                     
00662                     Iterator itCreatedNodes = createdNodes.iterator();
00663                     while(itCreatedNodes.hasNext()) {
00664                         
00665                         
00666                         
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                                 
00679                                 
00680                                 deGraph.addChildNode(n, childNode);
00681                                 deGraph.getUnexpandedAlphaNodes().add(childNode);
00682                                 stats.numNodes++;
00683                                 stats.numAlphaNodes++;
00684                             } else {
00685                                 
00686                                 ++stats.numAlreadyExists;
00687                             }
00688                             
00689                         } else {
00690                             ++stats.numDFChainTooLong;
00691                         }
00692                         
00693                     }  
00694                     
00695                     
00696                     itUnexpNodes = deGraph.getUnexpandedAlphaNodes().iterator();
00697                     
00698                 }  
00699             
00700             }  
00701 
00702             else {
00703                 
00704             }
00705             
00706         }  
00707         
00708     }  
00709 
00710     
00711 
00712 
00713 
00714 
00715 
00716 
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);  
00725 
00726          
00727 
00728         Iterator itNodes = deGraph.iterator();
00729         while (itNodes.hasNext()) {
00730             DENode n = (DENode)itNodes.next();
00731 
00732             
00733 
00734              
00735             
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         }  
00781     }  
00782 
00783     
00784 
00785 
00786     protected ArrayList computeDEGraph(ArrayList diags, boolean computeBetaDE,
00787                                        int maxDFChainSize, boolean mergeDEs, 
00788                                        boolean discardOrderPerms) {
00789 
00790         assert(!mergeDEs || !discardOrderPerms);  
00791 
00792         
00793 
00794         
00795         
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         
00815        
00816         ArrayList des = new ArrayList();
00817         ArrayList newNodes;
00818 
00819         int searchNumIF = 1; 
00820         do {            
00821         
00822             
00823     
00824             
00825             addDiagsToDEGraph(substDiags, diagsMinNumIF, searchNumIF);
00826 
00827             
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             
00839             
00840             if (des.size() > 0) return des;
00841             else ++searchNumIF;            
00842 
00843         } while (searchNumIF <= maxNumIF); 
00844 
00845         return des;
00846 
00847     }  
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 
00901 
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         
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 {  
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         }  
00980 
00981         
00982         
00983         boolean consistent = theoremProver.checkConsistency(posAssumptions, negAssumptions);
00984         if (consistent) return null;
00985         else return theoremProver.getConflictSet();
00986 
00987     } 
00988 
00989     
00990 
00991 
00992 
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 
01011 
01012 
01013 
01014 
01015 
01016 
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         
01034         return result;
01035     }
01036 
01037     
01038 
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         
01052         return result;
01053     }
01054     
01055     
01056 
01057 
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         
01075         return result;
01076     }
01077 
01078     
01079 
01080 
01081     protected boolean conflictsWithDescendants(ConflictSet cs, DENode n, boolean computeBetaDE) {
01082      
01083         
01084 
01085         
01086         
01087         ModeAssignment constMA = n.getModeAssignment();  
01088         
01089 
01090         
01091 
01092         boolean result = true;  
01093 
01094         Iterator itCS = cs.iterator();
01095         while (itCS.hasNext()) {
01096             Mode csMode = (Mode)itCS.next();
01097             
01098             Component csComp = csMode.getComponent();
01099             
01100             Mode constMode = constMA.getMode(csComp);
01101             
01102             
01103 
01104             if (constMode != null) {  
01105                 
01106                 
01107 
01108                 
01109                 
01110 
01111                 if (! ( (constMode == csMode) 
01112                         || ((csMode.getType() == Mode.MODE_IF) 
01113                             && (constMode.getType() == Mode.MODE_DF)) )
01114                     ) {
01115                     
01116                     assert(false);  
01117                     
01118                     result = false;
01119                     break;
01120                 }
01121 
01122             } else {  
01123 
01124                 
01125 
01126                 
01127 
01128                 if ((csMode.getType() == Mode.MODE_NAB) 
01129                     && (n.getModeAssignment().getMode(csComp) == null)) {  
01130                     
01131                     
01132 
01133                     
01134 
01135                     boolean constNAB = true;
01136 
01137                     
01138                     if (computeBetaDE && existsAncestor(csComp, n.getModeAssignment().iterator())) {
01139                         
01140                         constNAB = false;
01141                     }
01142 
01143                     
01144 
01145                     if (constNAB && (n.getType() == DENode.TYPE_ALPHA)) {
01146    
01147                         
01148                         if (existsDependentComp(csComp, 
01149                                                 n.getModeAssignment().getModeIterator(Mode.MODE_IF),
01150                                                 n.getConstCompModes())) {
01151                             
01152                             
01153                             constNAB = false;
01154                         }
01155                         
01156                         
01157                         if (constNAB  && computeBetaDE
01158                             &&  existsCommonAncestor(csComp, n.getModeAssignment().getModeIterator(Mode.MODE_IF),
01159                                                      n.getConstCompModes())) {
01160 
01161                             
01162                             constNAB = false;
01163                         }                                                             
01164                         
01165                     }                    
01166 
01167                     
01168 
01169                     if (!constNAB) {
01170                         result = false;
01171                         break;
01172                     }
01173 
01174                 } else {  
01175                     
01176                     result = false;
01177                     break;
01178                 }
01179                 
01180             }
01181         }
01182 
01183         
01184         return result;
01185 
01186     }  
01187 
01188     
01189 
01190 
01191 
01192 
01193     protected ConflictSet searchConflictForNode(DENode n) {
01194         
01195         
01196 
01197         if (n.hasParents()) {
01198             Iterator itParents = n.getParentsIterator();
01199             if (itParents.hasNext()) {
01200                 DENode parent = (DENode)itParents.next();
01201                 assert(!itParents.hasNext()); 
01202                 ConflictSet cs = parent.getConflictSet();
01203                 if ((cs != null) && cs.conflictsWith(n.getModeAssignment())) {
01204                     
01205                     return cs;
01206                 }
01207             }
01208         }
01209 
01210         
01211 
01212         return conflictSets.conflictsWith(n.getModeAssignment());
01213     }
01214 
01215     
01216 
01217 
01218 
01219 
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()) {  
01228             n.setConsistent(DENode.STATUS_TRUE);            
01229             
01230             result = true;  
01231         }
01232         
01233         else {  
01234 
01235             ModeAssignment ma = n.getModeAssignment();
01236         
01237             
01238             
01239             ConflictSet cs = searchConflictForNode(n);
01240             if (cs != null) {  
01241                 assert(callTheoremProver(ma) != null);
01242                 
01243                 n.setConsistent(DENode.STATUS_FALSE);
01244                 n.setConflictSet(cs);
01245                 stats.numConflicting++;
01246 
01247                 
01248 
01249                 
01250 
01251                 if (conflictsWithDescendants(cs, n, computeBetaDE)) {
01252                     deGraph.propagateInconsToDesc(n);
01253                     ++stats.numDescInconsistent;
01254                 }
01255 
01256                 result = false;
01257             }
01258         
01259             else {  
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                 
01269 
01270                 if (consistent) {
01271                     n.setConsistent(DENode.STATUS_TRUE);
01272                     result = true;
01273                 }
01274                 else {
01275 
01276                     
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     }  
01298 
01299     protected ArrayList expandNodeAlpha(DENode n) {
01300 
01301         ArrayList result = new ArrayList();
01302         TreeSet ccm = null;
01303         
01304         
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                 
01319                 if (!ccm.contains(m)) {  
01320                     
01321                     
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                         
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                         
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                 }  
01348             }  
01349 
01350         }  
01351 
01352         return result;
01353 
01354     }  
01355 
01356     protected ArrayList expandNodeBeta(DENode n) {
01357         
01358         ArrayList result = new ArrayList();
01359         TreeSet ccm = null;
01360         
01361         
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             
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                 
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                     
01392 
01393                     Mode mode_df_c_i = c_i.getMode(Mode.MODE_DF, c);
01394                     if (!ccm.contains(mode_df_c_i)) {
01395                         
01396                         
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                 }  
01409                 
01410             }  
01411 
01412         }  
01413 
01414         return result;
01415 
01416     }  
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         
01435         
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 
01461 
01462 
01463 
01464 
01465 
01466 
01467 
01468 
01469 
01470 
01471 
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 }