// Make sure that nobody else has the same element id
if (seen_ids.containsKey(e.getElementId())) {
String msg = String.format("Duplicate element id #%d: Edge[%s] <-> %s",
e.getElementId(), e.toString(true),
seen_ids.get(e.getElementId()));
throw new InvalidGraphElementException(this, e, msg);
}
seen_ids.put(e.getElementId(), e);
} // FOR
// Validate Vertices
Set<MarkovVertex> seen_vertices = new HashSet<MarkovVertex>();
PartitionSet all_partitions = new PartitionSet();
for (MarkovVertex v0 : this.getVertices()) {
float total_prob = 0.0f;
long total_edgehits = 0;
// Make sure the vertex thinks it's valid
v0.validate(this);
Collection<MarkovEdge> outbound = this.getOutEdges(v0);
Collection<MarkovEdge> inbound = this.getInEdges(v0);
// Make sure that nobody else has the same element id
if (seen_ids.containsKey(v0.getElementId())) {
throw new InvalidGraphElementException(this, v0, String.format("Duplicate element id #%d: Vertex[%s] <-> %s",
v0.getElementId(), v0, seen_ids.get(v0.getElementId())));
}
seen_ids.put(v0.getElementId(), v0);
all_partitions.addAll(v0.partitions);
all_partitions.addAll(v0.past_partitions);
for (MarkovEdge e : outbound) {
MarkovVertex v1 = this.getOpposite(v0, e);
// Make sure that each vertex only has one edge to another vertex
if (seen_vertices.contains(v1)) {
throw new InvalidGraphElementException(this, v0, "Vertex has more than one edge to vertex " + v1);
}
seen_vertices.add(v1);
// The totalhits for this vertex should always be greater than or equal to the total hints for
// all of its edges and equal to the sum
if (v0.getTotalHits() < e.getTotalHits()) {
throw new InvalidGraphElementException(this, v0, String.format("Vertex has %d totalHits but edge from %s to %s has %d",
v0.getTotalHits(), v0, v1, e.getTotalHits()));
}
// Make sure that this the destination vertex has the same partitions as the past+current partitions
// for the destination vertex
if (v0.isQueryVertex() && v1.isQueryVertex() && v1.past_partitions.equals(all_partitions) == false) {
v1.past_partitions.equals(all_partitions);
throw new InvalidGraphElementException(this, e, "Destination vertex in edge does not have the correct past partitions");
}
// Make sure that if the two vertices are for the same Statement, that
// the source vertex's instance counter is one less than the destination
if (v0.getCatalogKey().equals(v1.getCatalogKey())) {
if (v0.counter+1 != v1.counter) {
throw new InvalidGraphElementException(this, e, String.format("Invalid edge in from multiple invocations of %s: %d+1 != %d",
this.catalog_proc.getName(), v0.counter, v1.counter));
}
}
// Calculate total edge probabilities and hits
total_prob += e.getProbability();
total_edgehits += e.getTotalHits();
} // FOR
if (v0.isQueryVertex()) {
if (MathUtil.equals(total_prob, 1.0f, MarkovGraph.PROBABILITY_EPSILON) == false && outbound.size() > 0) {
throw new InvalidGraphElementException(this, v0, "Total outbound edge probability is not equal to one: " + total_prob);
}
if (total_edgehits != v0.getTotalHits()) {
throw new InvalidGraphElementException(this, v0, String.format("Vertex has %d totalHits but the sum of all its edges has %d",
v0.getTotalHits(), total_edgehits));
}
}
total_prob = 0.0f;
total_edgehits = 0;
for (MarkovEdge e : inbound) {
total_prob += e.getProbability();
total_edgehits += e.getTotalHits();
} // FOR
if (MathUtil.greaterThan(total_prob, 0.0f, MarkovGraph.PROBABILITY_EPSILON) == false && inbound.size() > 0 && total_edgehits > 0) {
throw new InvalidGraphElementException(this, v0, "Total inbound edge probability is not greater than zero: " + total_prob);
}
seen_vertices.clear();
all_partitions.clear();
} // FOR