/** * Check to see if we have found a solution to the problem. TODO: we could throw an exception to * simulate a non-local exit here, since we've assumed that P is the unity set. * * @param uCls * @param vCls * @param index */ protected static void checkSolution(OntClass uCls, OntClass vCls, LCAIndex index) { DisjointSet vSet = index.getSet(vCls); DisjointSet uSet = index.getSet(uCls); if (vSet != null && vSet.isBlack() && !vSet.used() && uSet != null && uSet.isBlack() && !uSet.used()) { vSet.setUsed(); uSet.setUsed(); // log.debug( "Found LCA: u = " + uCls + ", v = " + vCls ); OntClass lca = (OntClass) vSet.find().getAncestor().getNode(); // log.debug( "Found LCA: lca = " + lca ); index.setLCA(uCls, vCls, lca); } }
/** * Compute the LCA disjoint set at <code>cls</code>, noting that we are searching for the LCA of * <code>uCls</code> and <code>vCls</code>. * * @param cls The class we are testing (this is 'u' in the Wiki article) * @param uCls One of the two classes we are searching for the LCA of. We have simplified the set * P of pairs to the unity set {uCls,vCls} * @param vCls One of the two classes we are searching for the LCA of. We have simplified the set * P of pairs to the unity set {uCls,vCls} * @param index A data structure mapping resources to disjoint sets (since we can't side-effect * Jena resources), and which is used to record the LCA pairs */ protected static DisjointSet lca(OntClass cls, OntClass uCls, OntClass vCls, LCAIndex index) { // log.debug( "Entering lca(), cls = " + cls ); DisjointSet clsSet = index.getSet(cls); if (clsSet.isBlack()) { // already visited return clsSet; } // not visited yet clsSet.setAncestor(clsSet); // for each child of cls for (Iterator<OntClass> i = cls.listSubClasses(true); i.hasNext(); ) { OntClass child = i.next(); if (child.equals(cls) || child.equals(cls.getProfile().NOTHING())) { // we ignore the reflexive case and bottom continue; } // compute the LCA of the sub-tree DisjointSet v = lca(child, uCls, vCls, index); // union the two disjoint sets together clsSet.union(v); // propagate the distinguished member clsSet.find().setAncestor(clsSet); } // this node is done clsSet.setBlack(); // are we inspecting one of the elements we're interested in? if (cls.equals(uCls)) { checkSolution(uCls, vCls, index); } else if (cls.equals(vCls)) { checkSolution(vCls, uCls, index); } return clsSet; }
/** * The union of two sets * * @param y */ public void union(DisjointSet y) { DisjointSet xRoot = find(); DisjointSet yRoot = y.find(); if (xRoot.getRank() > yRoot.getRank()) { yRoot.setParent(xRoot); } else if (yRoot.getRank() > xRoot.getRank()) { xRoot.setParent(yRoot); } else if (xRoot != yRoot) { yRoot.setParent(xRoot); xRoot.incrementRank(); } }