/** * Answer the lowest common ancestor of two classes in a given ontology. This is the class that is * farthest from the root concept (defaulting to <code>owl:Thing</code> which is a super-class of * both <code>u</code> and <code>v</code>. The algorithm is based on <a * href="http://en.wikipedia.org/wiki/Tarjan's_off-line_least_common_ancestors_algorithm">Tarjan's * off-line LCA</a>. The current implementation expects that the given model: * * <ul> * <li>is transitively closed over the <code>subClassOf</code> relation * <li>can cheaply determine <em>direct sub-class</em> relations * </ul> * * <p>Both of these conditions are true of the built-in Jena OWL reasoners, such as {@link * OntModelSpec#OWL_MEM_MICRO_RULE_INF}, and external DL reasoners such as Pellet. * * @param m The ontology model being queried to find the LCA, which should conform to the reasoner * capabilities described above * @param u An ontology class * @param v An ontology class * @return The LCA of <code>u</code> and <code>v</code> * @exception JenaException if the language profile of the given model does not define a top * concept (e.g. <code>owl:Thing</code>) */ public static OntClass getLCA(OntModel m, OntClass u, OntClass v) { Resource root = m.getProfile().THING(); if (root == null) { throw new JenaException( "The given OntModel has a language profile that does not define a generic root class (such as owl:Thing)"); } root = root.inModel(m); return getLCA(m, root.as(OntClass.class), u, v); }
/** * 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; }