Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 package hittingsetalg;
00031
00032 import java.io.*;
00033 import java.util.*;
00034
00035 import theoremprover.*;
00036 import utils.SortedIntList;
00037
00047 public class MinHittingSets {
00048
00049 protected final static int CS_COMPUTING = 0;
00050
00051 public final static int CS_ALL_MIN_DIAGS_COMPUTED = 1;
00052
00053 public final static int CS_MAX_HS_SIZE_REACHED = 2;
00054
00055 public final static int CS_MAX_NUM_MIN_HS_REACHED = 3;
00056
00057
00058
00059 protected ArrayList computedMinHS = new ArrayList();
00060
00061
00062 protected int maxHSSize;
00063
00064
00065 protected int maxNumMinHS;
00066
00067
00068 protected boolean conflictsAreMinimal;
00069
00070
00071
00072
00073
00074
00075 protected ArrayList conflictSets = null;
00076
00077
00078 protected ABTheoremProver theoremProver = null;
00079
00080
00081 protected ArrayList assumptions = null;
00082
00083
00084
00085 protected SortedIntList components = null;
00086
00087
00088 protected boolean computeIncr;
00089
00090
00091 protected HSNode rootNode = null;
00092
00093
00094 protected ArrayList levels = new ArrayList();
00095
00096 protected int computationState = -1;
00097
00098 protected HSNode attemptedPruneNode = null;
00099
00100
00113 public MinHittingSets(boolean conflictsAreMinimal, ArrayList conflictSets) {
00114
00115 assert(conflictSets.size() >= 1);
00116
00117 computeIncr = false;
00118 this.conflictsAreMinimal = conflictsAreMinimal;
00119 this.conflictSets = conflictSets;
00120 }
00121
00130 public MinHittingSets(boolean conflictsAreMinimal,
00131 ABTheoremProver tp) {
00132
00133 assert((tp != null) && (tp.getAssumptions().size() > 0));
00134
00135 computeIncr = true;
00136 this.conflictsAreMinimal = conflictsAreMinimal;
00137 this.conflictSets = new ArrayList();
00138 this.theoremProver = tp;
00139
00140
00141 assumptions = tp.getAssumptions();
00142 components = new SortedIntList();
00143 Iterator it = assumptions.iterator();
00144 int tag = 0;
00145 System.out.println("Assumption tags: ");
00146 while(it.hasNext()) {
00147 Assumption a = (Assumption)it.next();
00148 a.setIntTag(tag);
00149 System.out.println((new Integer(tag)).toString() + ": " + (String)a.identifier);
00150 components.addSorted(tag);
00151 ++tag;
00152 }
00153
00154 System.out.println();
00155 }
00156
00165 public ArrayList getMinHS() {
00166
00167 if (theoremProver == null) {
00168 throw new UnsupportedOperationException("class MinHittingSets: if no theorem prover is used "
00169 + "for the dynamic computation of conflicts sets, then "
00170 + "getMinHSAsIntegers() must be used instead of "
00171 + "getMinHS() !!");
00172 }
00173
00174 ArrayList result = new ArrayList();
00175 result.ensureCapacity(computedMinHS.size());
00176
00177 Iterator itMinHS = computedMinHS.iterator();
00178 while (itMinHS.hasNext()) {
00179 HSNode node = (HSNode)itMinHS.next();
00180 if (node.state != HSNode.STATE_PRUNED) {
00181 assert(node.state == HSNode.STATE_MINIMAL);
00182
00183 ArrayList candidate = new ArrayList();
00184 Iterator itAss = node.edgeLabels.iterator();
00185 while (itAss.hasNext()) {
00186 Integer index = (Integer)itAss.next();
00187 candidate.add(theoremProver.getAssumptions().get(index.intValue()));
00188 }
00189 result.add(candidate);
00190
00191 }
00192 }
00193
00194 return result;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204 public ArrayList getMinHSAsIntLists() {
00205 ArrayList result = new ArrayList();
00206 result.ensureCapacity(computedMinHS.size());
00207
00208 Iterator itMinHS = computedMinHS.iterator();
00209 while (itMinHS.hasNext()) {
00210 HSNode node = (HSNode)itMinHS.next();
00211 if (node.state != HSNode.STATE_PRUNED) {
00212 assert(node.state == HSNode.STATE_MINIMAL);
00213
00214 result.add(node.edgeLabels);
00215 }
00216 }
00217
00218 return result;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 public ArrayList getConflictsAsAss() {
00228 ArrayList result = new ArrayList();
00229
00230 Iterator itConflicts = conflictSets.iterator();
00231 while (itConflicts.hasNext()) {
00232 SortedIntList cs = (SortedIntList)itConflicts.next();
00233 if (cs != null) {
00234 ArrayList csAss = new ArrayList(cs.size());
00235
00236 Iterator itCS = cs.iterator();
00237 while (itCS.hasNext()) {
00238 int index = ((Integer)itCS.next()).intValue();
00239 Assumption a = (Assumption)assumptions.get(index);
00240 csAss.add(a);
00241 }
00242
00243 result.add(csAss);
00244 }
00245 }
00246
00247 return result;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 public int compute(int maxHSSize, int maxNumMinHS) {
00261
00262 assert((maxHSSize >= 1) && (maxNumMinHS >= 1));
00263
00264
00265
00266 computationState = CS_COMPUTING;
00267 this.maxHSSize = maxHSSize;
00268 this.maxNumMinHS = maxNumMinHS;
00269 LinkedList lastLevelNodes = new LinkedList();
00270 int lastLevel = 0;
00271 levels.add(lastLevelNodes);
00272
00273
00274
00275 rootNode = new HSNode();
00276 rootNode.edgeLabels = new SortedIntList();
00277 lastLevelNodes.add(rootNode);
00278
00279
00280
00281 while(computationState == CS_COMPUTING) {
00282
00283
00284
00285
00286 LinkedList newLevelNodes = new LinkedList();
00287 levels.add(newLevelNodes);
00288 processLastLevel(lastLevel, lastLevelNodes, newLevelNodes, true);
00289
00290
00291 lastLevelNodes = newLevelNodes;
00292 ++lastLevel;
00293
00294 if (computationState == CS_COMPUTING) {
00295 assert(lastLevelNodes.size() > 0);
00296 if (lastLevel - 1 == maxHSSize) computationState = CS_MAX_HS_SIZE_REACHED;
00297 }
00298 }
00299
00300 assert(computationState != CS_COMPUTING);
00301 return computationState;
00302
00303 }
00304
00305 public int computeMore(int newMaxHSSize, int newMaxNumMinHS) {
00306 assert((newMaxHSSize >= maxHSSize) && (newMaxNumMinHS >= maxNumMinHS));
00307
00308 if (computationState == CS_ALL_MIN_DIAGS_COMPUTED) return CS_ALL_MIN_DIAGS_COMPUTED;
00309 else {
00310
00311 this.maxHSSize = newMaxHSSize;
00312 this.maxNumMinHS = newMaxNumMinHS;
00313 int lastLevel;
00314 LinkedList lastLevelNodes;
00315 LinkedList newLevelNodes;
00316
00317 if (computationState == CS_MAX_HS_SIZE_REACHED) {
00318 lastLevel = levels.size() - 1;
00319 lastLevelNodes = (LinkedList)levels.get(lastLevel);
00320 newLevelNodes = null;
00321 } else {
00322 assert(computationState == CS_MAX_NUM_MIN_HS_REACHED);
00323 lastLevel = levels.size() - 2;
00324 lastLevelNodes = (LinkedList)levels.get(lastLevel);
00325 newLevelNodes = (LinkedList)levels.get(lastLevel + 1);
00326 }
00327
00328 if (computedMinHS.size() == maxNumMinHS) computationState = CS_MAX_NUM_MIN_HS_REACHED;
00329 else if (lastLevel - 1 == maxHSSize) computationState = CS_MAX_HS_SIZE_REACHED;
00330 else computationState = CS_COMPUTING;
00331
00332 while(computationState == CS_COMPUTING) {
00333
00334 if (newLevelNodes == null) {
00335 newLevelNodes = new LinkedList();
00336 levels.add(newLevelNodes);
00337 }
00338
00339 processLastLevel(lastLevel, lastLevelNodes, newLevelNodes, true);
00340 lastLevelNodes = newLevelNodes;
00341 ++lastLevel;
00342
00343 if (computationState == CS_COMPUTING) {
00344 if (lastLevelNodes.size() == 0) computationState = CS_ALL_MIN_DIAGS_COMPUTED;
00345 else if (lastLevel - 1 == maxHSSize) computationState = CS_MAX_HS_SIZE_REACHED;
00346 }
00347 }
00348
00349 assert(computationState != CS_COMPUTING);
00350 return computationState;
00351 }
00352 }
00353
00354
00355
00356 protected SortedIntList callTheoremProver(SortedIntList edgeLabels) {
00357
00358 SortedIntList assumptionSet = components.subtract(edgeLabels);
00359
00360
00361
00362 Iterator itAss = assumptionSet.iterator();
00363 while(itAss.hasNext()) {
00364 int assIndex = ((Integer)itAss.next()).intValue();
00365 Assumption a = (Assumption)assumptions.get(assIndex);
00366
00367 if (a.getLabel() != true) {
00368 a.setLabel(true);
00369 a.propagateTrue();
00370 }
00371 }
00372
00373
00374
00375 Iterator itNegAss = edgeLabels.iterator();
00376 while(itNegAss.hasNext()) {
00377 int negassIndex = ((Integer)itNegAss.next()).intValue();
00378 Assumption a = (Assumption)assumptions.get(negassIndex);
00379
00380 if (a.getLabel() != false)
00381 {
00382 ArrayList v = new ArrayList();
00383 v = a.propagateFalse(v);
00384 Iterator ve = v.iterator();
00385 while (ve.hasNext()) {
00386 Proposition p = (Proposition)ve.next();
00387 p.correctLabels();
00388 }
00389 }
00390 }
00391
00392
00393
00394
00395
00396 if (theoremProver.isConsistent()) {
00397
00398 return null;
00399 } else {
00400
00401
00402
00403 ArrayList conflicts = theoremProver.contradiction().collectAssumptions();
00404 SortedIntList cs = new SortedIntList();
00405 Iterator itConflicts = conflicts.iterator();
00406 while(itConflicts.hasNext()) {
00407 Assumption a = (Assumption)itConflicts.next();
00408 cs.addSorted(a.getIntTag());
00409 }
00410
00411
00412 return cs;
00413 }
00414
00415 }
00416
00417
00418
00419
00420
00421
00422 protected void prune(HSNode node, HSNode prunedParent) {
00423
00424 assert(nodeInvariant(node));
00425
00426 if ((node.state == HSNode.STATE_OPEN) || (node.state == HSNode.STATE_MINIMAL)) {
00427
00428 boolean hasAliveParents;
00429 if (node.parents.size() == 1) hasAliveParents = false;
00430 else {
00431 assert(node.parents.size() > 1);
00432
00433 hasAliveParents = false;
00434
00435 Iterator itParents = node.parents.iterator();
00436 while (itParents.hasNext()) {
00437 HSNode parent = (HSNode)itParents.next();
00438 if ((parent != prunedParent) && (parent.state != HSNode.STATE_PRUNED)) {
00439 hasAliveParents = true;
00440 break;
00441 }
00442 }
00443 }
00444
00445 if (!hasAliveParents) {
00446
00447 node.state = HSNode.STATE_PRUNED;
00448
00449
00450
00451 Iterator itChildren = node.children.iterator();
00452 while (itChildren.hasNext()) {
00453 HSNode child = ((EdgeNodePair)itChildren.next()).node;
00454 if (child.state != HSNode.STATE_PRUNED) {
00455 prune(child, node);
00456 }
00457 }
00458 }
00459 else {
00460
00461 }
00462 }
00463
00464 assert(nodeInvariant(node));
00465
00466 }
00467
00468
00469
00470
00471
00472
00473 protected void relabel(HSNode node, HSNode newNode) {
00474
00475
00476
00477 assert((node.state != HSNode.STATE_MINIMAL) && newNode.label.properSubsetOf(node.label));
00478 assert(nodeInvariant(node));
00479 assert(nodeInvariant(newNode));
00480 assert(newNode == attemptedPruneNode);
00481
00482
00483
00484 SortedIntList removeLabel = node.label.subtract(newNode.label);
00485 node.label = newNode.label;
00486 conflictSets.set(node.conflictSetIndex, newNode.label);
00487
00488 newNode.conflictSetIndex = node.conflictSetIndex;
00489
00490
00491
00492 int prunedChildrenCount = 0;
00493 Iterator itChildren = node.children.iterator();
00494 while (itChildren.hasNext()) {
00495 EdgeNodePair child = (EdgeNodePair)itChildren.next();
00496
00497 if (removeLabel.contains(child.edge)) {
00498
00499 if (child.node.state != HSNode.STATE_PRUNED) {
00500 prune(child.node, node);
00501 }
00502
00503 ++prunedChildrenCount;
00504 }
00505
00506
00507 }
00508 assert(prunedChildrenCount == removeLabel.size());
00509
00510 assert(nodeInvariant(node));
00511 assert(nodeInvariant(newNode));
00512 assert(node.label.equals(newNode.label));
00513 }
00514
00515
00516
00517 protected int computeNumUnprunedChildren(HSNode node) {
00518 int n = 0;
00519 Iterator itChildren = node.children.iterator();
00520 while (itChildren.hasNext()) {
00521 HSNode child = ((EdgeNodePair)itChildren.next()).node;
00522 if (child.state != HSNode.STATE_PRUNED) ++n;
00523 }
00524
00525 return n;
00526 }
00527
00528
00529
00530 protected void attemptPrune(HSNode node) {
00531
00532
00533 assert((node.state == HSNode.STATE_OPEN) && (node.label != null)
00534 && (node.label.size() > 0) && (node != rootNode) && nodeInvariant(node));
00535
00536 attemptedPruneNode = node;
00537 int oldConflictSetIndex = node.conflictSetIndex;
00538 boolean pruned = false;
00539
00540
00541 rootNode.relevantForPruning = true;
00542 boolean relevantNodesExist = true;
00543
00544
00545
00546 Iterator itLevels = levels.iterator();
00547 while(itLevels.hasNext() && relevantNodesExist) {
00548
00549 relevantNodesExist = false;
00550
00551 LinkedList level = (LinkedList)itLevels.next();
00552 Iterator itLevelNodes = level.iterator();
00553
00554 SortedIntList intersectionSet = new SortedIntList();
00555
00556
00557
00558 while(itLevelNodes.hasNext()) {
00559
00560 HSNode otherNode = (HSNode)itLevelNodes.next();
00561
00562 if ((otherNode.state == HSNode.STATE_OPEN) && (otherNode.label != null)
00563 && otherNode.relevantForPruning) {
00564
00565
00566
00567 intersectionSet.clear();
00568 boolean intersects = otherNode.label.intersection(node.label, intersectionSet);
00569 assert((!intersects && (intersectionSet.size() == 0))
00570 || (intersects && (intersectionSet.size() != 0)));
00571
00572
00573
00574 boolean canPrune = (intersects && (intersectionSet.size() == node.label.size())
00575 && (node.label.size() < otherNode.label.size()));
00576 assert(!canPrune || node.label.properSubsetOf(otherNode.label));
00577
00578 if (canPrune) {
00579
00580 relabel(otherNode, node);
00581 pruned = true;
00582
00583 } else {
00584
00585 if ((intersectionSet.size() > 0)
00586 && (otherNode.children.size() > 0)) {
00587
00588
00589
00590 Iterator itIntersection = intersectionSet.iterator();
00591 int nextItem;
00592 if (itIntersection.hasNext())
00593 nextItem = ((Integer)itIntersection.next()).intValue();
00594 else nextItem = Integer.MAX_VALUE;
00595
00596 Iterator itChildren = otherNode.children.iterator();
00597 while (itChildren.hasNext()) {
00598 EdgeNodePair child = (EdgeNodePair)itChildren.next();
00599
00600 if (child.edge == nextItem) {
00601 child.node.relevantForPruning = false;
00602 assert(node.label.contains(child.edge));
00603 if (itIntersection.hasNext())
00604 nextItem = ((Integer)itIntersection.next()).intValue();
00605 else nextItem = Integer.MAX_VALUE;
00606 } else {
00607 child.node.relevantForPruning = true;
00608 relevantNodesExist = true;
00609 }
00610 }
00611
00612 assert(!itIntersection.hasNext());
00613
00614 } else {
00615
00616 Iterator itChildren = otherNode.children.iterator();
00617 while (itChildren.hasNext()) {
00618 HSNode child = ((EdgeNodePair)itChildren.next()).node;
00619 child.relevantForPruning = true;
00620 }
00621 relevantNodesExist = true;
00622
00623 }
00624
00625 }
00626
00627 }
00628
00629 else if (!otherNode.relevantForPruning) {
00630
00631 Iterator itChildren = otherNode.children.iterator();
00632 while(itChildren.hasNext()) {
00633 HSNode child = ((EdgeNodePair)itChildren.next()).node;
00634 child.relevantForPruning = false;
00635 }
00636
00637 }
00638
00639 }
00640
00641 }
00642
00643 if (pruned) conflictSets.set(oldConflictSetIndex, null);
00644 attemptedPruneNode = null;
00645
00646 assert(nodeInvariant(node));
00647
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 protected int searchRefutingCS(SortedIntList edgeLabel) {
00659 for (int i = 0; i < conflictSets.size(); ++i) {
00660 Object o = conflictSets.get(i);
00661 if (o != null) {
00662 SortedIntList cs = (SortedIntList)conflictSets.get(i);
00663 assert(cs.size() > 0);
00664 if (!edgeLabel.intersects(cs)) return i;
00665 }
00666 }
00667
00668 return -1;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 protected void computeLabel(HSNode node) {
00678
00679 assert((node.state == HSNode.STATE_OPEN) && (node.label == null)
00680 && nodeInvariant(node));
00681
00682
00683
00684 if (canClose(node)) {
00685 node.state = HSNode.STATE_CLOSED;
00686
00687 }
00688
00689 else {
00690
00691 if (computeIncr) {
00692
00693 int existingCSIndex = searchRefutingCS(node.edgeLabels);
00694 if (existingCSIndex >= 0) {
00695 assert(callTheoremProver(node.edgeLabels) != null);
00696 SortedIntList existingCS = (SortedIntList)conflictSets.get(existingCSIndex);
00697 node.label = existingCS;
00698 node.conflictSetIndex = existingCSIndex;
00699
00700 if (!conflictsAreMinimal && (node != rootNode)) attemptPrune(node);
00701 }
00702 else {
00703 SortedIntList cs = callTheoremProver(node.edgeLabels);
00704 if (cs == null) {
00705 node.state = HSNode.STATE_MINIMAL;
00706 }
00707 else {
00708 assert(cs.size() > 0);
00709 conflictSets.add(cs);
00710 node.label = cs;
00711 node.conflictSetIndex = conflictSets.size() - 1;
00712
00713 if (!conflictsAreMinimal && (node != rootNode)) attemptPrune(node);
00714 }
00715 }
00716
00717 }
00718
00719 else {
00720
00721 if (node.edgeLabels.size() == 0) {
00722 node.label = (SortedIntList)conflictSets.get(0);
00723 node.conflictSetIndex = 0;
00724 }
00725
00726 else {
00727
00728 Iterator itCS = conflictSets.iterator();
00729 int csIndex = 0;
00730 boolean hitsAllCS = true;
00731
00732
00733 while(itCS.hasNext() && hitsAllCS) {
00734 SortedIntList cs = (SortedIntList)itCS.next();
00735
00736 if (!node.edgeLabels.intersects(cs)) {
00737 hitsAllCS = false;
00738 node.label = cs;
00739 node.conflictSetIndex = csIndex;
00740 assert(cs.equals(conflictSets.get(csIndex)));
00741
00742 } else ++csIndex;
00743 }
00744
00745 if (hitsAllCS) {
00746 node.state = HSNode.STATE_MINIMAL;
00747
00748 } else {
00749 if (!conflictsAreMinimal && (node != rootNode)) attemptPrune(node);
00750 }
00751
00752 }
00753
00754 }
00755
00756
00757
00758 }
00759
00760 assert(nodeInvariant(node));
00761
00762 }
00763
00764
00765
00766 protected boolean canClose(HSNode node) {
00767
00768 assert(nodeInvariant(node));
00769
00770 Iterator itMinHS = computedMinHS.iterator();
00771 while (itMinHS.hasNext()) {
00772 HSNode n1 = (HSNode)itMinHS.next();
00773 if (n1.state == HSNode.STATE_MINIMAL) {
00774 SortedIntList hs = n1.edgeLabels;
00775 if (hs.subsetOf(node.edgeLabels)) {
00776 assert(hs.properSubsetOf(node.edgeLabels));
00777 return true;
00778 }
00779 } else assert(n1.state == HSNode.STATE_PRUNED);
00780 }
00781
00782 return false;
00783 }
00784
00785
00786
00787
00788
00789
00790 protected void processLastLevel(int lastLevel, LinkedList lastLevelNodes,
00791 LinkedList newLevelNodes, boolean expandNodes) {
00792
00793
00794
00795 boolean hasOpenNodes = false;
00796
00797 Iterator itLastNodes = lastLevelNodes.iterator();
00798 while(itLastNodes.hasNext()) {
00799
00800 HSNode node = (HSNode)itLastNodes.next();
00801 assert(nodeInvariant(node));
00802 if (node.state == HSNodeFM.STATE_OPEN) {
00803
00804 computeLabel(node);
00805
00806 if (node.state == HSNodeFM.STATE_MINIMAL) {
00807 computedMinHS.add(node);
00808 if (computedMinHS.size() == maxNumMinHS) {
00809 computationState = CS_MAX_NUM_MIN_HS_REACHED;
00810 break;
00811 }
00812 } else if (node.state == HSNodeFM.STATE_OPEN) {
00813 hasOpenNodes = true;
00814 if (expandNodes) {
00815 expandNode(node, newLevelNodes, lastLevel);
00816 }
00817 }
00818 }
00819
00820 assert(nodeInvariant(node));
00821
00822 }
00823
00824 if ((computationState == CS_COMPUTING) && !hasOpenNodes) {
00825 computationState = CS_ALL_MIN_DIAGS_COMPUTED;
00826 }
00827 }
00828
00829
00830
00831
00832
00833 protected void expandNode(HSNode node, LinkedList newNodes, int lastLevel) {
00834
00835 assert((node.label != null) && (node.label.size() >= 1) && nodeInvariant(node));
00836
00837 int oldNewNodesSize = newNodes.size();
00838
00839 int newEdge;
00840
00841
00842
00843 Iterator itLabel = node.label.iterator();
00844 while(itLabel.hasNext()) {
00845
00846
00847
00848 newEdge = ((Integer)itLabel.next()).intValue();
00849 SortedIntList newEdgeLabels = (SortedIntList)node.edgeLabels.clone();
00850 newEdgeLabels.addSorted(newEdge);
00851
00852
00853
00854
00855
00856
00857 boolean reused = false;
00858 Iterator itNewNodes = newNodes.iterator();
00859 for (int i = 0; i < oldNewNodesSize; ++i) {
00860 HSNode m = (HSNode)itNewNodes.next();
00861 if (newEdgeLabels.equals(m.edgeLabels)) {
00862 node.children.add(new EdgeNodePair(newEdge, m));
00863 m.parents.add(node);
00864 reused = true;
00865
00866 break;
00867 }
00868 }
00869
00870 if (!reused) {
00871
00872 HSNode newNode = new HSNode();
00873 newNode.edgeLabels = newEdgeLabels;
00874
00875 node.children.add(new EdgeNodePair(newEdge, newNode));
00876 newNode.parents.add(node);
00877 newNodes.add(newNode);
00878
00879
00880 }
00881
00882 }
00883
00884 assert(nodeInvariant(node));
00885
00886 }
00887
00888 public boolean checkMinimalityHS() {
00889
00890 for (int i = 0; i < computedMinHS.size(); ++i) {
00891
00892 HSNode node = (HSNode)computedMinHS.get(i);
00893
00894 if (node.state == HSNode.STATE_MINIMAL) {
00895
00896 for (int j = i + 1; j < computedMinHS.size(); ++j) {
00897
00898 HSNode otherNode = (HSNode)computedMinHS.get(j);
00899
00900 if ((otherNode.state == HSNode.STATE_MINIMAL)
00901 && node.edgeLabels.subsetOf(otherNode.edgeLabels)
00902 || otherNode.edgeLabels.subsetOf(node.edgeLabels)) return false;
00903
00904 }
00905 }
00906 }
00907
00908 return true;
00909 }
00910
00911 public boolean hitsAllConflictSets() {
00912
00913 for (int i = 0; i < computedMinHS.size(); ++i) {
00914
00915 HSNode node = (HSNode)computedMinHS.get(i);
00916 if (node.state == HSNode.STATE_MINIMAL) {
00917
00918 Iterator itCS = conflictSets.iterator();
00919 while (itCS.hasNext()) {
00920
00921 SortedIntList cs = (SortedIntList)itCS.next();
00922
00923 if (!node.edgeLabels.intersects(cs)) return false;
00924
00925 }
00926
00927 }
00928 }
00929
00930 return true;
00931
00932 }
00933
00934 protected boolean nodeInvariant(HSNode node) {
00935
00936 boolean a = ((node.label == null) || !node.label.intersects(node.edgeLabels));
00937 boolean b = ((node.conflictSetIndex == -1)
00938 || (node.label.equals(conflictSets.get(node.conflictSetIndex)))
00939 || ((attemptedPruneNode != null)
00940 && attemptedPruneNode.label.equals(conflictSets.get(node.conflictSetIndex))));
00941 boolean c = ((node == rootNode) || (node.parents.size() >= 1));
00942
00943 boolean result = (a && b && c);
00944
00945 if (!result) {
00946 if (!a) {
00947 System.out.println("NODE INVARIANT VIOLATED: a");
00948 System.out.println("node.label: " + node.label);
00949 System.out.println("node.edgeLabels: " + node.edgeLabels);
00950 }
00951 if (!b) System.out.println("NODE INVARIANT VIOLATED: b");
00952 if (!c) System.out.println("NODE INVARIANT VIOLATED: c");
00953 }
00954
00955 if (!b) {
00956 System.out.println("node: " + node + " | "
00957 + (SortedIntList)conflictSets.get(node.conflictSetIndex)
00958 + " conflictSetIndex: " + node.conflictSetIndex);
00959 System.out.print("attemptedPruneNode: ");
00960 if (attemptedPruneNode != null) {
00961 System.out.print("" + attemptedPruneNode);
00962 System.out.println(" conflictSetIndex: " + attemptedPruneNode.conflictSetIndex);
00963 System.out.println(conflictSets.get(attemptedPruneNode.conflictSetIndex));
00964 } else System.out.println("null");
00965 }
00966
00967 return result;
00968
00969
00970
00971
00972 }
00973 }
00974
00975
00976 class EdgeNodePair {
00977
00978 public int edge = -1;
00979
00980 public HSNode node;
00981
00982 public EdgeNodePair(int edge, HSNode node) {
00983 this.edge = edge;
00984 this.node = node;
00985 }
00986
00987 }
00988
00989
00990 class HSNode {
00991
00992 final static int STATE_OPEN = 0;
00993 final static int STATE_CLOSED = 1;
00994 final static int STATE_MINIMAL = 2;
00995 final static int STATE_PRUNED = 3;
00996
00997 int state = STATE_OPEN;
00998
00999
01000 SortedIntList edgeLabels;
01001
01002
01003 ArrayList parents = new ArrayList();
01004
01005
01006 ArrayList children = new ArrayList();
01007
01008 SortedIntList label;
01009
01010
01011 int conflictSetIndex = -1;
01012
01013
01014
01015 boolean relevantForPruning = true;
01016
01017 public String toString() {
01018
01019 String result = "{" + edgeLabels + "}; ";
01020
01021 if ((state == STATE_OPEN) || (state == STATE_PRUNED)) {
01022 if (label == null) result = result + "{??}";
01023 else {
01024 result = result + "{" + label + "}";
01025 }
01026 if (state == STATE_PRUNED) result = result + " PRUNED";
01027 }
01028 else if (state == STATE_CLOSED) {
01029 result = result + "X";
01030 } else if (state == STATE_MINIMAL) {
01031 result = result + "!!!";
01032 }
01033
01034 result = result + " csIndex: " + conflictSetIndex;
01035
01036 result = result + " #(parents): " + parents.size()
01037 + " #(children): " + children.size();
01038
01039 return result;
01040 }
01041
01042
01043 }