X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FNode.java;h=1d5e05a7206796b83605604a8493b0bb533d7463;hp=b360071aeadae7bdb68f6eb83ef6cd9715b6607f;hb=fe637b465179cf2a217bbfc76d12bc41551b4ac4;hpb=fc8cad4de7decd07e23f26ccfadb5e6d1ce291d5 diff --git a/src/edu/berkeley/sbp/Node.java b/src/edu/berkeley/sbp/Node.java index b360071..1d5e05a 100644 --- a/src/edu/berkeley/sbp/Node.java +++ b/src/edu/berkeley/sbp/Node.java @@ -26,11 +26,43 @@ final class Node public boolean merge(Result r) { if (results.contains(r)) return true; results.add(r); + r.addChild(this); if (fromEmptyReduction) return false; state.invokeReductions(phase().getToken(), this, false, r); return false; } + private boolean destroyed = false; + public boolean check() { + boolean dead = true; + // - all nodes must have a parent + // - non-doomed nodes must either: + // - be on the frontier or + // - have a non-doomed node closer to the frontier than themself + + if (phase.isFrontier()) dead = false; + for(Result r : children) + if (state.doomed) { if (r.usedByAnyNode()) dead = false; } + else { if (r.usedByNonDoomedNode()) dead = false; } + dead |= results.size()==0; + if (!dead || destroyed) return dead; + destroyed = true; + while(children.size()>0) + for(Result r : children) { + children.remove(r); + r.destroy(); + break; + } + while(results.size()>0) + for(Result r : results) { + results.remove(r); + r.removeChild(this); + r.check(); + break; + } + return dead; + } + ////////////////////////////////////////////////////////////////////// private static int node_idx = 0; @@ -41,6 +73,10 @@ final class Node private final boolean fromEmptyReduction; //private FastSet results = new FastSet(); private HashSet results = new HashSet(); + private HashSet children = new HashSet(); + public void removeChild(Result child) { children.remove(child); } + public void removeResult(Result result) { results.remove(result); } + public void addChild(Result child) { children.add(child); } public final void invoke(Position r, Boolean emptyProductions, Result only) { if (emptyProductions != (r.pos==0)) return; @@ -72,6 +108,7 @@ final class Node this.state = state; this.fromEmptyReduction = fromEmptyReduction; results.add(result); + result.addChild(this); if (phase.hash.get(state, result.phase()) != null) throw new Error("severe problem!"); phase.hash.put(state, result.phase(), this);