/** * Answer a list of the named hierarchy roots of a given {@link OntModel}. This will be similar to * the results of {@link OntModel#listHierarchyRootClasses()}, with the added constraint that * every member of the returned iterator will be a named class, not an anonymous class expression. * The named root classes are calculated from the root classes, by recursively replacing every * anonymous class with its direct sub-classes. Thus it can be seen that the values in the list * consists of the shallowest fringe of named classes in the hierarchy. * * @param m An ontology model * @return A list of classes whose members are the named root classes of the class hierarchy in * <code>m</code> */ public static List<OntClass> namedHierarchyRoots(OntModel m) { List<OntClass> nhr = new ArrayList<OntClass>(); // named roots List<OntClass> ahr = new ArrayList<OntClass>(); // anon roots // do the initial partition of the root classes partitionByNamed(m.listHierarchyRootClasses(), nhr, ahr); // now push the fringe down until we have only named classes while (!ahr.isEmpty()) { OntClass c = ahr.remove(0); partitionByNamed(c.listSubClasses(true), nhr, ahr); } return nhr; }
/** * 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; }