/** * Simple single-function interface to split and then update a graph * * @param graph the graph containing the vertices in toMerge * @param v The bottom node whose incoming vertices we'd like to split * @return true if some useful splitting was done, false otherwise */ public boolean split(final SeqGraph graph, final SeqVertex v) { if (graph == null) throw new IllegalArgumentException("graph cannot be null"); if (v == null) throw new IllegalArgumentException("v cannot be null"); if (!graph.vertexSet().contains(v)) throw new IllegalArgumentException("graph doesn't contain vertex v " + v); final Collection<SeqVertex> toSplit = graph.incomingVerticesOf(v); if (toSplit.size() < 2) // Can only split at least 2 vertices return false; else if (!safeToSplit(graph, v, toSplit)) { return false; } else { final SeqVertex suffixVTemplate = commonSuffix(toSplit); if (suffixVTemplate.isEmpty()) { return false; } else if (wouldEliminateRefSource(graph, suffixVTemplate, toSplit)) { return false; } else if (allVerticesAreTheCommonSuffix(suffixVTemplate, toSplit)) { return false; } else { final List<BaseEdge> edgesToRemove = new LinkedList<BaseEdge>(); // graph.printGraph(new File("split.pre_" + v.getSequenceString() + "." + // counter + ".dot"), 0); for (final SeqVertex mid : toSplit) { // create my own copy of the suffix final SeqVertex suffixV = new SeqVertex(suffixVTemplate.getSequence()); graph.addVertex(suffixV); final SeqVertex prefixV = mid.withoutSuffix(suffixV.getSequence()); final BaseEdge out = graph.outgoingEdgeOf(mid); final SeqVertex incomingTarget; if (prefixV == null) { // this node is entirely explained by suffix incomingTarget = suffixV; } else { incomingTarget = prefixV; graph.addVertex(prefixV); graph.addEdge(prefixV, suffixV, new BaseEdge(out.isRef(), 1)); edgesToRemove.add(out); } graph.addEdge(suffixV, graph.getEdgeTarget(out), out.copy()); for (final BaseEdge in : graph.incomingEdgesOf(mid)) { graph.addEdge(graph.getEdgeSource(in), incomingTarget, in.copy()); edgesToRemove.add(in); } } graph.removeAllVertices(toSplit); graph.removeAllEdges(edgesToRemove); // graph.printGraph(new File("split.post_" + v.getSequenceString() + "." + // counter++ + ".dot"), 0); return true; } } }