This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git


The following commit(s) were added to refs/heads/main by this push:
     new 6d3f0e65c3 GH-2487: optimize HierarchySupport#contains; add 
OntClass#hasSubClass & OntClass#hasSuperClass & OntProperty#hasSubProperty & 
OntProperty#hasSuperProperty + rename 
`OntSpecification.OWL2_DL_MEM_BUILTIN_INF` -> `OWL2_DL_MEM_BUILTIN_RDFS_INF` + 
minor changes in javadocs
6d3f0e65c3 is described below

commit 6d3f0e65c386ed91f82cf548a6c93ac7a941b19f
Author: sszuev <[email protected]>
AuthorDate: Sat Jun 8 19:03:49 2024 +0300

    GH-2487: optimize HierarchySupport#contains; add OntClass#hasSubClass & 
OntClass#hasSuperClass & OntProperty#hasSubProperty & 
OntProperty#hasSuperProperty + rename 
`OntSpecification.OWL2_DL_MEM_BUILTIN_INF` -> `OWL2_DL_MEM_BUILTIN_RDFS_INF` + 
minor changes in javadocs
---
 .../org/apache/jena/ontapi/OntModelControls.java   |   2 +-
 .../org/apache/jena/ontapi/OntModelFactory.java    |   6 +-
 .../org/apache/jena/ontapi/OntSpecification.java   |   2 +-
 .../apache/jena/ontapi/impl/HierarchySupport.java  |  98 ++++++-
 .../impl/objects/OntAnnotationPropertyImpl.java    |   7 +
 .../jena/ontapi/impl/objects/OntClassImpl.java     |  34 +++
 .../ontapi/impl/objects/OntDataPropertyImpl.java   |  11 +-
 .../ontapi/impl/objects/OntObjectPropertyImpl.java |  11 +-
 .../jena/ontapi/impl/objects/OntPropertyImpl.java  |  24 +-
 .../ontapi/impl/objects/OntSimpleClassImpl.java    |   5 +
 .../ontapi/impl/objects/OntSimplePropertyImpl.java |   5 +
 .../org/apache/jena/ontapi/model/OntClass.java     |  58 +++-
 .../org/apache/jena/ontapi/model/OntProperty.java  |  28 ++
 .../java/org/apache/jena/ontapi/utils/Graphs.java  |   5 +-
 .../org/apache/jena/ontapi/OntClassMiscTest.java   |  18 +-
 .../apache/jena/ontapi/OntClassSubClassesTest.java | 320 +++++++++++++++++++++
 .../jena/ontapi/OntClassSuperClassesTest.java      | 200 ++++++++++++-
 .../jena/ontapi/OntIndividualClassesTest.java      | 257 +++++++++++++++++
 .../java/org/apache/jena/ontapi/OntListTest.java   |   2 +-
 .../jena/ontapi/OntModelIndividualsTest.java       |   3 +-
 .../apache/jena/ontapi/OntModelOWL2QLSpecTest.java |   5 +-
 .../apache/jena/ontapi/OntModelOWL2RLSpecTest.java |   2 +-
 .../org/apache/jena/ontapi/OntPropertyTest.java    | 223 +++++++++++++-
 .../jena/ontapi/OntUnionGraphRepositoryTest.java   |  18 +-
 .../test/java/org/apache/jena/ontapi/TestSpec.java |   2 +-
 25 files changed, 1277 insertions(+), 69 deletions(-)

diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelControls.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelControls.java
index 10c5369610..72a4f7ae10 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelControls.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelControls.java
@@ -52,7 +52,7 @@ public enum OntModelControls {
      * are to be inferred by the naked model itself using builtin algorithms.
      * Should not be used in conjunction with Reasoner.
      *
-     * @see OntSpecification#OWL2_DL_MEM_BUILTIN_INF
+     * @see OntSpecification#OWL2_DL_MEM_BUILTIN_RDFS_INF
      */
     USE_BUILTIN_HIERARCHY_SUPPORT,
     /**
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelFactory.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelFactory.java
index 7e3f0e6582..2641c09747 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelFactory.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntModelFactory.java
@@ -133,7 +133,7 @@ public class OntModelFactory {
      * @return {@link OntModel}
      */
     public static OntModel createModel(Graph graph) {
-        return createModel(graph, 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF).setNsPrefixes(STANDARD);
+        return createModel(graph, 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF).setNsPrefixes(STANDARD);
     }
 
     /**
@@ -199,7 +199,7 @@ public class OntModelFactory {
     }
 
     /**
-     * Creates Ontology Model associated with {@link 
OntSpecification#OWL2_DL_MEM_BUILTIN_INF} spec.
+     * Creates Ontology Model associated with {@link 
OntSpecification#OWL2_DL_MEM_BUILTIN_RDFS_INF} spec.
      * The {@code repository} manages all the dependencies.
      * See {@link #createModel(Graph, OntSpecification, GraphRepository)}.
      *
@@ -211,7 +211,7 @@ public class OntModelFactory {
     public static OntModel createModel(String uri, GraphRepository repository) 
{
         return createModel(
                 createOntGraph(uri != null ? NodeFactory.createURI(uri) : 
NodeFactory.createBlankNode(), repository),
-                OntSpecification.OWL2_DL_MEM_BUILTIN_INF,
+                OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF,
                 repository
         ).setNsPrefixes(STANDARD);
     }
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntSpecification.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntSpecification.java
index 1c1fcfc029..e1c2327ed0 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntSpecification.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/OntSpecification.java
@@ -145,7 +145,7 @@ public class OntSpecification {
      *
      * @see org.apache.jena.ontology.OntModelSpec#OWL_DL_MEM_RDFS_INF
      */
-    public static final OntSpecification OWL2_DL_MEM_BUILTIN_INF = new 
OntSpecification(
+    public static final OntSpecification OWL2_DL_MEM_BUILTIN_RDFS_INF = new 
OntSpecification(
             OntPersonalities.OWL2_ONT_PERSONALITY()
                     .setBuiltins(OntPersonalities.OWL2_FULL_BUILTINS)
                     .setReserved(OntPersonalities.OWL2_RESERVED)
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/HierarchySupport.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/HierarchySupport.java
index e2b5ac6c19..25c026def3 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/HierarchySupport.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/HierarchySupport.java
@@ -57,8 +57,13 @@ public final class HierarchySupport {
             Function<X, Stream<X>> listChildren,
             boolean direct,
             boolean useBuiltinHierarchySupport) {
-        // TODO: optimize
-        return treeNodes(root, listChildren, direct, 
useBuiltinHierarchySupport).anyMatch(test::equals);
+        if (direct) {
+            return hasDirectNode(root, test, useBuiltinHierarchySupport, 
listChildren);
+        }
+        if (useBuiltinHierarchySupport) {
+            return hasIndirectNode(root, test, listChildren);
+        }
+        return !root.equals(test) && 
listChildren.apply(root).anyMatch(test::equals);
     }
 
     /**
@@ -83,31 +88,56 @@ public final class HierarchySupport {
             return directNodesAsStream(root, useBuiltinHierarchySupport, 
listChildren);
         }
         if (useBuiltinHierarchySupport) {
-            return allTreeNodes(root, listChildren);
+            return indirectNodesAsStream(root, listChildren);
         }
         return listChildren.apply(root).filter(x -> !root.equals(x));
     }
 
     /**
      * For the given object returns a {@code Set} of objects the same type,
-     * that are its children which is determined by the operation {@code 
listChildren}.
+     * that are its (direct or indirect) children which is determined by the 
operation {@code listChildren}.
      *
      * @param root         {@code X}
      * @param listChildren a {@code Function} that returns {@code Iterator} 
for an object of type {@code X}
      * @param <X>          any subtype of {@link Resource}
      * @return {@code Set} of {@code X}, {@code root} is not included
      */
-    static <X extends Resource> Stream<X> allTreeNodes(X root, Function<X, 
Stream<X>> listChildren) {
+    static <X extends Resource> Stream<X> indirectNodesAsStream(X root, 
Function<X, Stream<X>> listChildren) {
         return Iterators.fromSet(() -> {
             Set<X> res = new HashSet<>();
-            Map<X, Set<X>> childrenNodesCache = new HashMap<>();
-            Function<X, Set<X>> getChildren = it -> getChildren(it, 
listChildren, childrenNodesCache);
+            Function<X, Set<X>> getChildren = it -> 
listChildren.apply(it).collect(Collectors.toSet());
             collectIndirect(root, getChildren, res);
             res.remove(root);
             return res;
         });
     }
 
+    static <X extends Resource> boolean hasIndirectNode(X root, X test, 
Function<X, Stream<X>> listChildren) {
+        if (root.equals(test)) {
+            return false;
+        }
+        Set<X> seen = new HashSet<>();
+        Deque<X> queue = new ArrayDeque<>();
+        queue.add(root);
+        while (!queue.isEmpty()) {
+            X next = queue.removeFirst();
+            if (!seen.add(next)) {
+                continue;
+            }
+            try (Stream<X> children = listChildren.apply(next)) {
+                Iterator<X> it = children.iterator();
+                while (it.hasNext()) {
+                    X child = it.next();
+                    if (child.equals(test)) {
+                        return true;
+                    }
+                    queue.add(child);
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * Returns a forest (collection of indirect node trees) for the given 
roots.
      *
@@ -158,12 +188,21 @@ public final class HierarchySupport {
         );
     }
 
+    public static <X extends Resource> boolean hasDirectNode(X object,
+                                                             X test,
+                                                             boolean 
useBuiltinHierarchySupport,
+                                                             Function<X, 
Stream<X>> listChildren) {
+        return useBuiltinHierarchySupport ?
+                hasDirectNodeWithBuiltinInf(object, test, listChildren) :
+                hasDirectNodeStandard(object, test, listChildren);
+    }
+
     public static <X extends Resource> Set<X> directNodesAsSetStandard(X root,
                                                                        
Function<X, Stream<X>> listChildren) {
         Map<X, Set<X>> childrenNodesCache = new HashMap<>();
         Function<X, Set<X>> getChildren = it -> getChildren(it, listChildren, 
childrenNodesCache);
         return getChildren.apply(root).stream()
-                .filter(x -> !equivalent(x, root, getChildren) && 
!hasAnotherPath(x, root, getChildren))
+                .filter(it -> !equivalent(it, root, getChildren) && 
!hasAnotherPath(it, root, getChildren))
                 .collect(Collectors.toSet());
     }
 
@@ -176,6 +215,24 @@ public final class HierarchySupport {
                 .collect(Collectors.toSet());
     }
 
+    public static <X extends Resource> boolean hasDirectNodeStandard(X root,
+                                                                     X test,
+                                                                     
Function<X, Stream<X>> listChildren) {
+        Map<X, Set<X>> childrenNodesCache = new HashMap<>();
+        Function<X, Set<X>> getChildren = it -> getChildren(it, listChildren, 
childrenNodesCache);
+        return getChildren.apply(root).stream()
+                .anyMatch(it -> test.equals(it) && !equivalent(it, root, 
getChildren) && !hasAnotherPath(it, root, getChildren));
+    }
+
+    public static <X extends Resource> boolean hasDirectNodeWithBuiltinInf(X 
root,
+                                                                           X 
test,
+                                                                           
Function<X, Stream<X>> listChildren) {
+        Map<X, Node<X>> tree = collectTree(root, listChildren);
+        Node<X> theRoot = tree.get(root);
+        return theRoot.childrenWithEquivalents().anyMatch(it -> 
hasDirectNode(theRoot, it, test));
+    }
+
+    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
     private static <X extends Resource> boolean hasAnotherPath(X given,
                                                                X root,
                                                                Function<X, 
Set<X>> getChildren) {
@@ -192,15 +249,15 @@ public final class HierarchySupport {
         return getChildren.apply(right).contains(left) && 
getChildren.apply(left).contains(right);
     }
 
-    private static <X extends Resource> Stream<X> collectDirect(Node<X> 
rootNode, Node<X> it) {
-        Set<X> equivalents = it.equivalents();
+    private static <X extends Resource> Stream<X> collectDirect(Node<X> 
rootNode, Node<X> current) {
+        Set<X> equivalents = current.equivalents();
         if (!equivalents.contains(rootNode.node)) {
             Set<X> siblings = new HashSet<>(equivalents);
-            siblings.remove(it.node);
-            if (it.hasMoreThanOnePathTo(rootNode, siblings)) {
+            siblings.remove(current.node);
+            if (current.hasMoreThanOnePathTo(rootNode, siblings)) {
                 return Stream.empty();
             } else {
-                equivalents.add(it.node);
+                equivalents.add(current.node);
                 return equivalents.stream();
             }
         } else {
@@ -208,6 +265,21 @@ public final class HierarchySupport {
         }
     }
 
+    private static <X extends Resource> boolean hasDirectNode(Node<X> 
rootNode, Node<X> current, X test) {
+        Set<X> equivalents = current.equivalents();
+        if (!equivalents.contains(rootNode.node)) {
+            Set<X> siblings = new HashSet<>(equivalents);
+            siblings.remove(current.node);
+            if (current.hasMoreThanOnePathTo(rootNode, siblings)) {
+                return false;
+            } else {
+                return current.node.equals(test) || equivalents.contains(test);
+            }
+        } else {
+            return false;
+        }
+    }
+
     private static <X extends Resource> Map<X, Node<X>> collectTree(X root, 
Function<X, Stream<X>> listChildren) {
         Map<X, Set<X>> childrenNodesCache = new HashMap<>();
         Map<X, Node<X>> res = new HashMap<>();
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntAnnotationPropertyImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntAnnotationPropertyImpl.java
index 63a1499e39..3f8b07b753 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntAnnotationPropertyImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntAnnotationPropertyImpl.java
@@ -22,6 +22,7 @@ import org.apache.jena.enhanced.EnhGraph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.ontapi.model.OntAnnotationProperty;
 import org.apache.jena.ontapi.model.OntClass;
+import org.apache.jena.ontapi.model.OntProperty;
 import org.apache.jena.ontapi.model.OntStatement;
 import org.apache.jena.rdf.model.Model;
 import org.apache.jena.rdf.model.Property;
@@ -83,6 +84,12 @@ public class OntAnnotationPropertyImpl extends 
OntPropertyImpl implements OntAnn
         return declaringClasses(this, direct);
     }
 
+    @Override
+    public boolean hasSuperProperty(OntProperty property, boolean direct) {
+        return property.canAs(OntAnnotationProperty.class) &&
+                OntPropertyImpl.hasSuperProperty(this, 
property.as(OntAnnotationProperty.class), OntAnnotationProperty.class, direct);
+    }
+
     @Override
     public boolean isBuiltIn() {
         return getModel().isBuiltIn(this);
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
index 23236a1f8b..5f801a5adb 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntClassImpl.java
@@ -435,6 +435,9 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     public static Stream<OntClass> subClasses(OntClass clazz, boolean direct) {
+        if (clazz.asSuperClass() == null) {
+            return Stream.empty();
+        }
         if (direct) {
             Property reasonerProperty = reasonerProperty(clazz.getModel(), 
RDFS.subClassOf);
             if (reasonerProperty != null) {
@@ -450,6 +453,9 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
     }
 
     public static Stream<OntClass> superClasses(OntClass clazz, boolean 
direct) {
+        if (clazz.asSubClass() == null) {
+            return Stream.empty();
+        }
         if (direct) {
             Property reasonerProperty = reasonerProperty(clazz.getModel(), 
RDFS.subClassOf);
             if (reasonerProperty != null) {
@@ -464,6 +470,29 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
         );
     }
 
+    public static boolean hasSuperClass(OntClass clazz, OntClass 
candidateSuper, boolean direct) {
+        if (clazz.equals(candidateSuper)) {
+            // every class is a subclass of itself
+            return true;
+        }
+        if (clazz.asSubClass() == null || candidateSuper.asSuperClass() == 
null) {
+            return false;
+        }
+        if (direct) {
+            Property reasonerProperty = reasonerProperty(clazz.getModel(), 
RDFS.subClassOf);
+            if (reasonerProperty != null) {
+                return clazz.getModel().contains(clazz, reasonerProperty, 
candidateSuper);
+            }
+        }
+        return HierarchySupport.contains(
+                clazz,
+                candidateSuper,
+                it -> explicitSuperClasses(RDFS.subClassOf, it),
+                direct,
+                OntGraphModelImpl.configValue(clazz.getModel(), 
OntModelControls.USE_BUILTIN_HIERARCHY_SUPPORT)
+        );
+    }
+
     static Stream<OntClass> explicitSuperClasses(Property predicate, OntObject 
clazz) {
         return clazz.objects(predicate, 
OntClass.class).map(OntClass::asSuperClass).filter(Objects::nonNull);
     }
@@ -548,6 +577,11 @@ public abstract class OntClassImpl extends OntObjectImpl 
implements OntClass {
         return equivalentClasses(getModel(), this);
     }
 
+    @Override
+    public boolean hasSuperClass(OntClass clazz, boolean direct) {
+        return OntClassImpl.hasSuperClass(this, clazz, direct);
+    }
+
     @Override
     public OntStatement addEquivalentClassStatement(OntClass other) {
         return addEquivalentClass(getModel(), this, other);
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDataPropertyImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDataPropertyImpl.java
index 90e0afa183..2e3fcd617b 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDataPropertyImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntDataPropertyImpl.java
@@ -26,6 +26,7 @@ import org.apache.jena.ontapi.model.OntClass;
 import org.apache.jena.ontapi.model.OntDataProperty;
 import org.apache.jena.ontapi.model.OntIndividual;
 import org.apache.jena.ontapi.model.OntNegativeAssertion;
+import org.apache.jena.ontapi.model.OntProperty;
 import org.apache.jena.ontapi.model.OntStatement;
 import org.apache.jena.rdf.model.Literal;
 import org.apache.jena.rdf.model.Model;
@@ -66,6 +67,12 @@ public class OntDataPropertyImpl extends OntPropertyImpl 
implements OntDataPrope
         return declaringClasses(this, direct);
     }
 
+    @Override
+    public boolean hasSuperProperty(OntProperty property, boolean direct) {
+        return property.canAs(OntDataProperty.class) &&
+                OntPropertyImpl.hasSuperProperty(this, 
property.as(OntDataProperty.class), OntDataProperty.class, direct);
+    }
+
     @Override
     public Stream<OntDataProperty> disjointProperties() {
         return OntPropertyImpl.disjointProperties(getModel(), 
OntDataProperty.class, this);
@@ -73,7 +80,7 @@ public class OntDataPropertyImpl extends OntPropertyImpl 
implements OntDataPrope
 
     @Override
     public OntStatement addPropertyDisjointWithStatement(OntDataProperty 
other) {
-        return OntPropertyImpl.addDisjointWith(getModel(), 
OntDataProperty.class, this, other);
+        return OntPropertyImpl.addDisjointWith(getModel(), this, other);
     }
 
     @Override
@@ -89,7 +96,7 @@ public class OntDataPropertyImpl extends OntPropertyImpl 
implements OntDataPrope
 
     @Override
     public OntStatement addEquivalentPropertyStatement(OntDataProperty other) {
-        return OntPropertyImpl.addEquivalentProperty(getModel(), 
OntDataProperty.class, this, other);
+        return OntPropertyImpl.addEquivalentProperty(getModel(), this, other);
     }
 
     @Override
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntObjectPropertyImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntObjectPropertyImpl.java
index 0fe4eb2854..b446cb181a 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntObjectPropertyImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntObjectPropertyImpl.java
@@ -30,6 +30,7 @@ import org.apache.jena.ontapi.model.OntList;
 import org.apache.jena.ontapi.model.OntNegativeAssertion;
 import org.apache.jena.ontapi.model.OntObject;
 import org.apache.jena.ontapi.model.OntObjectProperty;
+import org.apache.jena.ontapi.model.OntProperty;
 import org.apache.jena.ontapi.model.OntStatement;
 import org.apache.jena.ontapi.utils.Iterators;
 import org.apache.jena.rdf.model.Model;
@@ -71,6 +72,12 @@ public abstract class OntObjectPropertyImpl extends 
OntPropertyImpl implements O
         return declaringClasses(this, direct);
     }
 
+    @Override
+    public boolean hasSuperProperty(OntProperty property, boolean direct) {
+        return property.canAs(OntObjectProperty.class) &&
+                OntPropertyImpl.hasSuperProperty(this, 
property.as(OntObjectProperty.class), OntObjectProperty.class, direct);
+    }
+
     @Override
     public OntNegativeAssertion.WithObjectProperty 
addNegativeAssertion(OntIndividual source, OntIndividual target) {
         return OntNegativePropertyAssertionImpl.create(getModel(), source, 
this, target);
@@ -104,7 +111,7 @@ public abstract class OntObjectPropertyImpl extends 
OntPropertyImpl implements O
 
     @Override
     public OntStatement addPropertyDisjointWithStatement(OntObjectProperty 
other) {
-        return addDisjointWith(getModel(), OntObjectProperty.class, this, 
other);
+        return addDisjointWith(getModel(), this, other);
     }
 
     @Override
@@ -120,7 +127,7 @@ public abstract class OntObjectPropertyImpl extends 
OntPropertyImpl implements O
 
     @Override
     public OntStatement addEquivalentPropertyStatement(OntObjectProperty 
other) {
-        return addEquivalentProperty(getModel(), OntObjectProperty.class, 
this, other);
+        return addEquivalentProperty(getModel(), this, other);
     }
 
     @Override
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntPropertyImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntPropertyImpl.java
index 29b6e15cdc..1d24a1cee2 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntPropertyImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntPropertyImpl.java
@@ -94,6 +94,26 @@ public abstract class OntPropertyImpl extends OntObjectImpl 
implements OntProper
         );
     }
 
+    public static <X extends OntProperty> boolean hasSuperProperty(X property, 
X candidateSuper, Class<X> type, boolean direct) {
+        if (property.equals(candidateSuper)) {
+            // every property is a sub-property of itself
+            return true;
+        }
+        if (direct) {
+            Property reasonerProperty = reasonerProperty(property.getModel(), 
RDFS.subPropertyOf);
+            if (reasonerProperty != null) {
+                return property.getModel().contains(property, 
reasonerProperty, candidateSuper);
+            }
+        }
+        return HierarchySupport.contains(
+                property,
+                candidateSuper,
+                it -> explicitSuperProperties(it, RDFS.subPropertyOf, type),
+                direct,
+                OntGraphModelImpl.configValue(property.getModel(), 
OntModelControls.USE_BUILTIN_HIERARCHY_SUPPORT)
+        );
+    }
+
     public static <X extends OntRelationalProperty> Stream<X> 
disjointProperties(OntGraphModelImpl m, Class<X> type, X property) {
         if (!OntGraphModelImpl.configValue(m, 
OntModelControls.USE_OWL2_PROPERTY_DISJOINT_WITH_FEATURE)) {
             return Stream.empty();
@@ -101,7 +121,7 @@ public abstract class OntPropertyImpl extends OntObjectImpl 
implements OntProper
         return property.objects(OWL2.propertyDisjointWith, type);
     }
 
-    public static <X extends OntRelationalProperty> OntStatement 
addDisjointWith(OntGraphModelImpl m, Class<X> type, X property, X other) {
+    public static <X extends OntRelationalProperty> OntStatement 
addDisjointWith(OntGraphModelImpl m, X property, X other) {
         OntGraphModelImpl.checkFeature(m, 
OntModelControls.USE_OWL2_PROPERTY_DISJOINT_WITH_FEATURE, 
"owl:propertyDisjointWith");
         return property.addStatement(OWL2.propertyDisjointWith, other);
     }
@@ -118,7 +138,7 @@ public abstract class OntPropertyImpl extends OntObjectImpl 
implements OntProper
         return property.objects(OWL2.equivalentProperty, type);
     }
 
-    public static <X extends OntRelationalProperty> OntStatement 
addEquivalentProperty(OntGraphModelImpl m, Class<X> type, X property, X other) {
+    public static <X extends OntRelationalProperty> OntStatement 
addEquivalentProperty(OntGraphModelImpl m, X property, X other) {
         OntGraphModelImpl.checkFeature(m, 
OntModelControls.USE_OWL_PROPERTY_EQUIVALENT_FEATURE, "owl:equivalentProperty");
         return property.addStatement(OWL2.equivalentProperty, other);
     }
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
index 20dcbb70ef..4ea15e4a7d 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimpleClassImpl.java
@@ -141,6 +141,11 @@ public class OntSimpleClassImpl extends OntObjectImpl 
implements OntClass {
         return OntClassImpl.equivalentClasses(getModel(), this);
     }
 
+    @Override
+    public boolean hasSuperClass(OntClass clazz, boolean direct) {
+        return OntClassImpl.hasSuperClass(this, clazz, direct);
+    }
+
     @Override
     public OntClass addDisjointClass(OntClass other) {
         OntClassImpl.addDisjoint(getModel(), this, other);
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimplePropertyImpl.java
 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimplePropertyImpl.java
index f1f30d2465..642bd3cde1 100644
--- 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimplePropertyImpl.java
+++ 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/impl/objects/OntSimplePropertyImpl.java
@@ -78,6 +78,11 @@ public class OntSimplePropertyImpl extends OntPropertyImpl 
implements OntPropert
         return declaringClasses(this, direct);
     }
 
+    @Override
+    public boolean hasSuperProperty(OntProperty property, boolean direct) {
+        return OntPropertyImpl.hasSuperProperty(this, property, 
OntProperty.class, direct);
+    }
+
     @Override
     public Resource inModel(Model m) {
         return getModel() == m ? this : m.getRDFNode(asNode()).asResource();
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
index cc6e88a6b0..ecce5daaa6 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntClass.java
@@ -377,6 +377,9 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @return {@link Optional} wrapping {@link OntClass}
      */
     default Optional<OntClass> subClass() {
+        if (asSuperClass() == null) {
+            return Optional.empty();
+        }
         try (Stream<OntClass> classes = getModel()
                 .statements(null, RDFS.subClassOf, this)
                 .map(OntStatement::getSubject)
@@ -409,6 +412,9 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
      * @return {@link Optional} wrapping {@link OntClass}
      */
     default Optional<OntClass> superClass() {
+        if (asSubClass() == null) {
+            return Optional.empty();
+        }
         try (Stream<OntClass> classes = this.statements(RDFS.subClassOf)
                 .map(OntStatement::getSubject)
                 .filter(it -> it.canAs(OntClass.class))
@@ -418,6 +424,35 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
         }
     }
 
+    /**
+     * Answers {@code true}
+     * if the given class is a subclass of this class.
+     * See {@link #subClasses(boolean)} for a full explanation of the direct 
parameter.
+     *
+     * @param clazz  a {@link OntClass} to test
+     * @param direct {@code boolean}; If true, only search the classes
+     *               that are directly adjacent to this class in the class 
hierarchy
+     * @return {@code boolean}
+     */
+    default boolean hasSubClass(OntClass clazz, boolean direct) {
+        return clazz.hasSuperClass(this, direct);
+    }
+
+    /**
+     * Answers {@code true}
+     * if the given class is a superclass of this class.
+     * See {@link #superClasses(boolean)} for a full explanation of the direct 
parameter
+     *
+     * @param clazz  a {@link OntClass} to test
+     * @param direct {@code boolean}; If true, only search the classes
+     *               that are directly adjacent to this class in the class 
hierarchy.
+     * @return {@code boolean}
+     */
+    default boolean hasSuperClass(OntClass clazz, boolean direct) {
+        return equals(clazz) ||
+                (asSubClass() != null && clazz.asSuperClass() != null && 
superClasses(direct).anyMatch(clazz::equals));
+    }
+
     /**
      * Lists all {@code OntDisjoint} sections where this class is a member.
      *
@@ -693,9 +728,11 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
     }
 
     /**
-     * Returns this class if the specification allows it to be in subclass 
position, otherwise returns {@code null}.
+     * Returns the subclass-view of this class
+     * if the specification allows this class to be in subclass position, 
otherwise returns {@code null}.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
+     * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
      */
@@ -704,9 +741,11 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
     }
 
     /**
-     * Returns this class if the specification allows it to be in superclass 
position, otherwise returns {@code null}.
+     * Returns the superclass-view of this class
+     * if the specification allows this class to be in superclass position, 
otherwise returns {@code null}.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
+     * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
      */
@@ -715,9 +754,11 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
     }
 
     /**
-     * Returns this class if the specification allows it to make class 
assertions, otherwise returns {@code null}.
+     * Returns the assertion-view of this class
+     * if the specification allows this class to make class assertions, 
otherwise returns {@code null}.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
+     * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
      */
@@ -726,10 +767,12 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
     }
 
     /**
-     * Returns this class if the specification allows it to be in equivalent
-     * ({@code owl:equivalentClass}) position, otherwise returns {@code null}.
+     * Returns the equivalent-class-view of this class
+     * if the specification allows this class to be in equivalent
+     * position ({@code owl:equivalentClass}), otherwise returns {@code null}.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
+     * Note that the returned class may differ in behavior from this class.
      *
      * @return {@link OntClass} or {@code null}
      */
@@ -738,8 +781,9 @@ public interface OntClass extends OntObject, 
AsNamed<OntClass.Named>, HasDisjoin
     }
 
     /**
-     * Returns this class if the specification allows it to be in disjoint
-     * ({@code owl:disjointWith}, {@code owl:AllDisjointClasses}) position, 
otherwise returns {@code null}.
+     * Returns the disjoint-class-view of this class
+     * if the specification allows this to be in disjoint position
+     * ({@code owl:disjointWith}, {@code owl:AllDisjointClasses}), otherwise 
returns {@code null}.
      * Some profiles (e.g., OWL2 QL, OWL2 RL)
      * distinguish constructions with respect to their position in the axiom 
statements.
      *
diff --git 
a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntProperty.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntProperty.java
index 16922f264e..d9e522755c 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntProperty.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/model/OntProperty.java
@@ -189,6 +189,34 @@ public interface OntProperty extends OntObject {
         return superProperties(false);
     }
 
+    /**
+     * Answers {@code true}
+     * if the given property is a sub-property of this property.
+     * See {@link #subProperties(boolean)} for a full explanation of the 
direct parameter.
+     *
+     * @param property a {@link OntProperty} to test
+     * @param direct {@code boolean}; If true, only search the properties
+     *               that are directly adjacent to this property in the class 
hierarchy
+     * @return {@code boolean}
+     */
+    default boolean hasSubProperty(OntProperty property, boolean direct) {
+        return property.hasSuperProperty(this, direct);
+    }
+
+    /**
+     * Answers {@code true}
+     * if the given property is a super-property of this property.
+     * See {@link #superProperties(boolean)} for a full explanation of the 
direct parameter.
+     *
+     * @param property a {@link OntProperty} to test
+     * @param direct {@code boolean}; If true, only search the properties
+     *               that are directly adjacent to this property in the class 
hierarchy
+     * @return {@code boolean}
+     */
+    default boolean hasSuperProperty(OntProperty property, boolean direct) {
+        return equals(property) || 
superProperties(direct).anyMatch(property::equals);
+    }
+
     /**
      * Adds the given property as super property returning a new statement to 
annotate.
      * The triple pattern is {@code $this rdfs:subPropertyOf $property}).
diff --git a/jena-ontapi/src/main/java/org/apache/jena/ontapi/utils/Graphs.java 
b/jena-ontapi/src/main/java/org/apache/jena/ontapi/utils/Graphs.java
index 3a0576d795..2bf3da8c68 100644
--- a/jena-ontapi/src/main/java/org/apache/jena/ontapi/utils/Graphs.java
+++ b/jena-ontapi/src/main/java/org/apache/jena/ontapi/utils/Graphs.java
@@ -444,7 +444,6 @@ public class Graphs {
         if (id == null) {
             return false;
         }
-        Set<UnionGraph> res = new LinkedHashSet<>();
         Map<Node, UnionGraph> queue = new LinkedHashMap<>();
         queue.put(id, graph);
         Set<Node> seen = new HashSet<>();
@@ -596,8 +595,8 @@ public class Graphs {
      * Note: it works with any graph, not necessarily with the base.
      * A valid composite ontology graph a lot of ontological nodes are 
expected.
      * If {@code allowMultipleOntologyHeaders = true}, the most suitable 
ontology header will be chosen:
-     * if there are both uri and blank ontological nodes together in the 
graph, then it prefers uri;
-     * if there are several ontological nodes of the same kind, he chooses the 
most cumbersome one.
+     * if there are both uri and blank ontological nodes together in the 
graph, then the method prefers uri;
+     * if there are several ontological nodes of the same kind, it chooses the 
most cumbersome one.
      *
      * @param graph                        {@link Graph}
      * @param allowMultipleOntologyHeaders {@code boolean}
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassMiscTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassMiscTest.java
index 2f02e540db..7d4a9a6a80 100644
--- a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassMiscTest.java
+++ b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassMiscTest.java
@@ -41,7 +41,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testCreateCardinalityRestrictions() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass c = m.createOntClass("C");
         OntObjectProperty op = m.createObjectProperty("OP");
         OntDataProperty dp = m.createDataProperty("DP");
@@ -65,7 +65,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testListClassHierarchy() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass a = m.createOntClass("A");
         OntClass b = m.createOntClass("B");
         OntClass c = m.createOntClass("C");
@@ -83,7 +83,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testClassExpressionSubClassOf() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass a = m.createOntClass("A");
         OntClass b = m.createOntClass("B");
         OntClass c = m.createOntClass("C");
@@ -104,7 +104,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testClassExpressionDisjointWith() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass a = m.createOntClass("A");
         OntClass b = m.createOntClass("B");
         OntClass c = m.createOntClass("C");
@@ -117,7 +117,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testClassExpressionEquivalentClass() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass.Named a = m.createOntClass("A");
         OntClass.Named b = m.createOntClass("B");
         OntClass.Named c = m.createOntClass("C");
@@ -130,7 +130,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testHasKeys() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntObjectProperty o1 = m.createObjectProperty("O1");
         OntObjectProperty o2 = m.createObjectProperty("O2");
         OntDataProperty d1 = m.createDataProperty("D1");
@@ -150,7 +150,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testClassExpressionCollectionOf() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass c1 = m.createOntClass("C1");
         OntClass c2 = m.createOntClass("C2");
         OntClass c3 = m.createOntClass("C3");
@@ -186,7 +186,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testListDisjoints() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass c1 = m.createOntClass("C1");
         OntClass c2 = m.createOntClass("C2");
         OntClass c3 = m.createOntClass("C3");
@@ -202,7 +202,7 @@ public class OntClassMiscTest {
 
     @Test
     public void testIsDisjoint() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntClass c1 = m.createOntClass(":C1");
         OntClass c2 = m.createOntClass(":C2");
         OntClass c3 = m.createOntClass(":C3");
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSubClassesTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSubClassesTest.java
index 9c4bf71672..c2c8d79840 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSubClassesTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSubClassesTest.java
@@ -1575,4 +1575,324 @@ public class OntClassSubClassesTest {
         Assertions.assertEquals(Set.of("C", "Nothing"), indirectB, "wrong 
indirect nodes for B");
         Assertions.assertEquals(Set.of("B", "Nothing"), indirectC, "wrong 
indirect nodes for C");
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM",
+            "OWL2_MEM",
+            "OWL2_EL_MEM",
+            "OWL2_QL_MEM",
+            "OWL2_RL_MEM",
+            "OWL1_DL_MEM",
+            "OWL1_MEM",
+            "OWL1_LITE_MEM",
+            "RDFS_MEM",
+    })
+    public void testHasSubClasses1a(TestSpec spec) {
+        //      A
+        //     / \
+        //    B   C
+        //   / \ / \
+        //  D   E   F
+        OntModel m = 
createClassesABCDEF(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+        OntClass F = m.getOntClass(NS + "F");
+
+        Assertions.assertTrue(A.hasSubClass(A, false));
+        Assertions.assertTrue(A.hasSubClass(B, false));
+        Assertions.assertTrue(A.hasSubClass(C, false));
+        Assertions.assertFalse(A.hasSubClass(D, false));
+        Assertions.assertFalse(A.hasSubClass(E, false));
+        Assertions.assertFalse(A.hasSubClass(F, false));
+        Assertions.assertFalse(B.hasSubClass(A, false));
+        Assertions.assertTrue(B.hasSubClass(B, false));
+        Assertions.assertFalse(B.hasSubClass(C, false));
+        Assertions.assertTrue(B.hasSubClass(D, false));
+        Assertions.assertTrue(B.hasSubClass(E, false));
+        Assertions.assertFalse(B.hasSubClass(F, false));
+        Assertions.assertFalse(C.hasSubClass(A, false));
+        Assertions.assertFalse(C.hasSubClass(B, false));
+        Assertions.assertTrue(C.hasSubClass(C, false));
+        Assertions.assertFalse(C.hasSubClass(D, false));
+        Assertions.assertTrue(C.hasSubClass(E, false));
+        Assertions.assertTrue(C.hasSubClass(F, false));
+        Assertions.assertFalse(D.hasSubClass(A, false));
+        Assertions.assertFalse(D.hasSubClass(B, false));
+        Assertions.assertFalse(D.hasSubClass(C, false));
+        Assertions.assertTrue(D.hasSubClass(D, false));
+        Assertions.assertFalse(D.hasSubClass(E, false));
+        Assertions.assertFalse(D.hasSubClass(F, false));
+        Assertions.assertFalse(E.hasSubClass(A, false));
+        Assertions.assertFalse(E.hasSubClass(B, false));
+        Assertions.assertFalse(E.hasSubClass(C, false));
+        Assertions.assertFalse(E.hasSubClass(D, false));
+        Assertions.assertTrue(E.hasSubClass(E, false));
+        Assertions.assertFalse(E.hasSubClass(F, false));
+        Assertions.assertFalse(F.hasSubClass(A, false));
+        Assertions.assertFalse(F.hasSubClass(B, false));
+        Assertions.assertFalse(F.hasSubClass(C, false));
+        Assertions.assertFalse(F.hasSubClass(D, false));
+        Assertions.assertFalse(F.hasSubClass(E, false));
+        Assertions.assertTrue(F.hasSubClass(F, false));
+
+        Assertions.assertTrue(A.hasSubClass(A, true));
+        Assertions.assertTrue(A.hasSubClass(B, true));
+        Assertions.assertTrue(A.hasSubClass(C, true));
+        Assertions.assertFalse(A.hasSubClass(D, true));
+        Assertions.assertFalse(A.hasSubClass(E, true));
+        Assertions.assertFalse(A.hasSubClass(F, true));
+        Assertions.assertFalse(B.hasSubClass(A, true));
+        Assertions.assertTrue(B.hasSubClass(B, true));
+        Assertions.assertFalse(B.hasSubClass(C, true));
+        Assertions.assertTrue(B.hasSubClass(D, true));
+        Assertions.assertTrue(B.hasSubClass(E, true));
+        Assertions.assertFalse(B.hasSubClass(F, true));
+        Assertions.assertFalse(C.hasSubClass(A, true));
+        Assertions.assertFalse(C.hasSubClass(B, true));
+        Assertions.assertTrue(C.hasSubClass(C, true));
+        Assertions.assertFalse(C.hasSubClass(D, true));
+        Assertions.assertTrue(C.hasSubClass(E, true));
+        Assertions.assertTrue(C.hasSubClass(F, true));
+        Assertions.assertFalse(D.hasSubClass(A, true));
+        Assertions.assertFalse(D.hasSubClass(B, true));
+        Assertions.assertFalse(D.hasSubClass(C, true));
+        Assertions.assertTrue(D.hasSubClass(D, true));
+        Assertions.assertFalse(D.hasSubClass(E, true));
+        Assertions.assertFalse(D.hasSubClass(F, true));
+        Assertions.assertFalse(E.hasSubClass(A, true));
+        Assertions.assertFalse(E.hasSubClass(B, true));
+        Assertions.assertFalse(E.hasSubClass(C, true));
+        Assertions.assertFalse(E.hasSubClass(D, true));
+        Assertions.assertTrue(E.hasSubClass(E, true));
+        Assertions.assertFalse(E.hasSubClass(F, true));
+        Assertions.assertFalse(F.hasSubClass(A, true));
+        Assertions.assertFalse(F.hasSubClass(B, true));
+        Assertions.assertFalse(F.hasSubClass(C, true));
+        Assertions.assertFalse(F.hasSubClass(D, true));
+        Assertions.assertFalse(F.hasSubClass(E, true));
+        Assertions.assertTrue(F.hasSubClass(F, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_RDFS_BUILTIN_INF",
+            "OWL2_DL_MEM_RDFS_INF",
+            "OWL2_DL_MEM_RULES_INF",
+            "OWL2_MEM_RDFS_INF",
+            "OWL2_MEM_RULES_INF",
+            "OWL2_MEM_MINI_RULES_INF",
+            "OWL2_MEM_MICRO_RULES_INF",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_RULES_INF",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_RULES_INF",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_RULES_INF",
+            "OWL1_DL_MEM_RDFS_INF",
+            "OWL1_DL_MEM_RULES_INF",
+            "OWL1_MEM_RDFS_INF",
+            "OWL1_MEM_RULES_INF",
+            "OWL1_MEM_MINI_RULES_INF",
+            "OWL1_MEM_MICRO_RULES_INF",
+            "OWL1_LITE_MEM_RDFS_INF",
+            "OWL1_LITE_MEM_RULES_INF",
+            "RDFS_MEM_RDFS_INF",
+    })
+    public void testHasSubClasses1b(TestSpec spec) {
+        //      A
+        //     / \
+        //    B   C
+        //   / \ / \
+        //  D   E   F
+        OntModel m = 
createClassesABCDEF(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+        OntClass F = m.getOntClass(NS + "F");
+
+        Assertions.assertTrue(A.hasSubClass(A, false));
+        Assertions.assertTrue(A.hasSubClass(B, false));
+        Assertions.assertTrue(A.hasSubClass(C, false));
+        Assertions.assertTrue(A.hasSubClass(D, false));
+        Assertions.assertTrue(A.hasSubClass(E, false));
+        Assertions.assertTrue(A.hasSubClass(F, false));
+        Assertions.assertFalse(B.hasSubClass(A, false));
+        Assertions.assertTrue(B.hasSubClass(B, false));
+        Assertions.assertFalse(B.hasSubClass(C, false));
+        Assertions.assertTrue(B.hasSubClass(D, false));
+        Assertions.assertTrue(B.hasSubClass(E, false));
+        Assertions.assertFalse(B.hasSubClass(F, false));
+        Assertions.assertFalse(C.hasSubClass(A, false));
+        Assertions.assertFalse(C.hasSubClass(B, false));
+        Assertions.assertTrue(C.hasSubClass(C, false));
+        Assertions.assertFalse(C.hasSubClass(D, false));
+        Assertions.assertTrue(C.hasSubClass(E, false));
+        Assertions.assertTrue(C.hasSubClass(F, false));
+        Assertions.assertFalse(D.hasSubClass(A, false));
+        Assertions.assertFalse(D.hasSubClass(B, false));
+        Assertions.assertFalse(D.hasSubClass(C, false));
+        Assertions.assertTrue(D.hasSubClass(D, false));
+        Assertions.assertFalse(D.hasSubClass(E, false));
+        Assertions.assertFalse(D.hasSubClass(F, false));
+        Assertions.assertFalse(E.hasSubClass(A, false));
+        Assertions.assertFalse(E.hasSubClass(B, false));
+        Assertions.assertFalse(E.hasSubClass(C, false));
+        Assertions.assertFalse(E.hasSubClass(D, false));
+        Assertions.assertTrue(E.hasSubClass(E, false));
+        Assertions.assertFalse(E.hasSubClass(F, false));
+        Assertions.assertFalse(F.hasSubClass(A, false));
+        Assertions.assertFalse(F.hasSubClass(B, false));
+        Assertions.assertFalse(F.hasSubClass(C, false));
+        Assertions.assertFalse(F.hasSubClass(D, false));
+        Assertions.assertFalse(F.hasSubClass(E, false));
+        Assertions.assertTrue(F.hasSubClass(F, false));
+
+        Assertions.assertTrue(A.hasSubClass(A, true));
+        Assertions.assertTrue(A.hasSubClass(B, true));
+        Assertions.assertTrue(A.hasSubClass(C, true));
+        Assertions.assertFalse(A.hasSubClass(D, true));
+        Assertions.assertFalse(A.hasSubClass(E, true));
+        Assertions.assertFalse(A.hasSubClass(F, true));
+        Assertions.assertFalse(B.hasSubClass(A, true));
+        Assertions.assertTrue(B.hasSubClass(B, true));
+        Assertions.assertFalse(B.hasSubClass(C, true));
+        Assertions.assertTrue(B.hasSubClass(D, true));
+        Assertions.assertTrue(B.hasSubClass(E, true));
+        Assertions.assertFalse(B.hasSubClass(F, true));
+        Assertions.assertFalse(C.hasSubClass(A, true));
+        Assertions.assertFalse(C.hasSubClass(B, true));
+        Assertions.assertTrue(C.hasSubClass(C, true));
+        Assertions.assertFalse(C.hasSubClass(D, true));
+        Assertions.assertTrue(C.hasSubClass(E, true));
+        Assertions.assertTrue(C.hasSubClass(F, true));
+        Assertions.assertFalse(D.hasSubClass(A, true));
+        Assertions.assertFalse(D.hasSubClass(B, true));
+        Assertions.assertFalse(D.hasSubClass(C, true));
+        Assertions.assertTrue(D.hasSubClass(D, true));
+        Assertions.assertFalse(D.hasSubClass(E, true));
+        Assertions.assertFalse(D.hasSubClass(F, true));
+        Assertions.assertFalse(E.hasSubClass(A, true));
+        Assertions.assertFalse(E.hasSubClass(B, true));
+        Assertions.assertFalse(E.hasSubClass(C, true));
+        Assertions.assertFalse(E.hasSubClass(D, true));
+        Assertions.assertTrue(E.hasSubClass(E, true));
+        Assertions.assertFalse(E.hasSubClass(F, true));
+        Assertions.assertFalse(F.hasSubClass(A, true));
+        Assertions.assertFalse(F.hasSubClass(B, true));
+        Assertions.assertFalse(F.hasSubClass(C, true));
+        Assertions.assertFalse(F.hasSubClass(D, true));
+        Assertions.assertFalse(F.hasSubClass(E, true));
+        Assertions.assertTrue(F.hasSubClass(F, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_TRANS_INF",
+            "OWL2_MEM_TRANS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+            "OWL1_DL_MEM_TRANS_INF",
+            "OWL1_MEM_TRANS_INF",
+            "OWL1_LITE_MEM_TRANS_INF",
+            "RDFS_MEM_TRANS_INF",
+    })
+    public void testHasSubClasses1c(TestSpec spec) {
+        //      A
+        //     / \
+        //    B   C
+        //   / \ / \
+        //  D   E   F
+        OntModel m = 
createClassesABCDEF(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+        OntClass F = m.getOntClass(NS + "F");
+
+        Assertions.assertTrue(A.hasSubClass(A, false));
+        Assertions.assertTrue(A.hasSubClass(B, false));
+        Assertions.assertTrue(A.hasSubClass(C, false));
+        Assertions.assertTrue(A.hasSubClass(D, false));
+        Assertions.assertTrue(A.hasSubClass(E, false));
+        Assertions.assertTrue(A.hasSubClass(F, false));
+        Assertions.assertFalse(B.hasSubClass(A, false));
+        Assertions.assertTrue(B.hasSubClass(B, false));
+        Assertions.assertFalse(B.hasSubClass(C, false));
+        Assertions.assertTrue(B.hasSubClass(D, false));
+        Assertions.assertTrue(B.hasSubClass(E, false));
+        Assertions.assertFalse(B.hasSubClass(F, false));
+        Assertions.assertFalse(C.hasSubClass(A, false));
+        Assertions.assertFalse(C.hasSubClass(B, false));
+        Assertions.assertTrue(C.hasSubClass(C, false));
+        Assertions.assertFalse(C.hasSubClass(D, false));
+        Assertions.assertTrue(C.hasSubClass(E, false));
+        Assertions.assertTrue(C.hasSubClass(F, false));
+        Assertions.assertFalse(D.hasSubClass(A, false));
+        Assertions.assertFalse(D.hasSubClass(B, false));
+        Assertions.assertFalse(D.hasSubClass(C, false));
+        Assertions.assertTrue(D.hasSubClass(D, false));
+        Assertions.assertFalse(D.hasSubClass(E, false));
+        Assertions.assertFalse(D.hasSubClass(F, false));
+        Assertions.assertFalse(E.hasSubClass(A, false));
+        Assertions.assertFalse(E.hasSubClass(B, false));
+        Assertions.assertFalse(E.hasSubClass(C, false));
+        Assertions.assertFalse(E.hasSubClass(D, false));
+        Assertions.assertTrue(E.hasSubClass(E, false));
+        Assertions.assertFalse(E.hasSubClass(F, false));
+        Assertions.assertFalse(F.hasSubClass(A, false));
+        Assertions.assertFalse(F.hasSubClass(B, false));
+        Assertions.assertFalse(F.hasSubClass(C, false));
+        Assertions.assertFalse(F.hasSubClass(D, false));
+        Assertions.assertFalse(F.hasSubClass(E, false));
+        Assertions.assertTrue(F.hasSubClass(F, false));
+
+        Assertions.assertTrue(A.hasSubClass(A, true));
+        Assertions.assertTrue(A.hasSubClass(B, true));
+        Assertions.assertTrue(A.hasSubClass(C, true));
+        Assertions.assertFalse(A.hasSubClass(D, true));
+        Assertions.assertFalse(A.hasSubClass(E, true));
+        Assertions.assertFalse(A.hasSubClass(F, true));
+        Assertions.assertFalse(B.hasSubClass(A, true));
+        Assertions.assertTrue(B.hasSubClass(B, true));
+        Assertions.assertFalse(B.hasSubClass(C, true));
+        Assertions.assertTrue(B.hasSubClass(D, true));
+        Assertions.assertTrue(B.hasSubClass(E, true));
+        Assertions.assertFalse(B.hasSubClass(F, true));
+        Assertions.assertFalse(C.hasSubClass(A, true));
+        Assertions.assertFalse(C.hasSubClass(B, true));
+        Assertions.assertTrue(C.hasSubClass(C, true));
+        Assertions.assertFalse(C.hasSubClass(D, true));
+        Assertions.assertTrue(C.hasSubClass(E, true));
+        Assertions.assertTrue(C.hasSubClass(F, true));
+        Assertions.assertFalse(D.hasSubClass(A, true));
+        Assertions.assertFalse(D.hasSubClass(B, true));
+        Assertions.assertFalse(D.hasSubClass(C, true));
+        Assertions.assertTrue(D.hasSubClass(D, true));
+        Assertions.assertFalse(D.hasSubClass(E, true));
+        Assertions.assertFalse(D.hasSubClass(F, true));
+        Assertions.assertFalse(E.hasSubClass(A, true));
+        Assertions.assertFalse(E.hasSubClass(B, true));
+        Assertions.assertFalse(E.hasSubClass(C, true));
+        Assertions.assertFalse(E.hasSubClass(D, true));
+        Assertions.assertTrue(E.hasSubClass(E, true));
+        Assertions.assertFalse(E.hasSubClass(F, true));
+        Assertions.assertFalse(F.hasSubClass(A, true));
+        Assertions.assertFalse(F.hasSubClass(B, true));
+        Assertions.assertFalse(F.hasSubClass(C, true));
+        Assertions.assertFalse(F.hasSubClass(D, true));
+        Assertions.assertFalse(F.hasSubClass(E, true));
+        Assertions.assertTrue(F.hasSubClass(F, true));
+    }
+
 }
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSuperClassesTest.java
 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSuperClassesTest.java
index 1ac7bffd0d..17588d24a9 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSuperClassesTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntClassSuperClassesTest.java
@@ -28,13 +28,15 @@ import org.junit.jupiter.params.provider.EnumSource;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.jena.ontapi.TestModelFactory.NS;
+
 public class OntClassSuperClassesTest {
     private static Set<String> superClasses(OntModel m, String name, boolean 
direct) {
-        return m.getOntClass(TestModelFactory.NS + 
name).superClasses(direct).map(Resource::getLocalName).collect(Collectors.toSet());
+        return m.getOntClass(NS + 
name).superClasses(direct).map(Resource::getLocalName).collect(Collectors.toSet());
     }
 
     private static Set<String> superClasses(OntModel m, String name) {
-        return m.getOntClass(TestModelFactory.NS + 
name).superClasses().map(Resource::getLocalName).collect(Collectors.toSet());
+        return m.getOntClass(NS + 
name).superClasses().map(Resource::getLocalName).collect(Collectors.toSet());
     }
 
     @ParameterizedTest
@@ -51,7 +53,7 @@ public class OntClassSuperClassesTest {
     })
     public void testSuperClassNE(TestSpec spec) {
         OntModel m = OntModelFactory.createModel(spec.inst);
-        OntClass a = m.createOntClass(TestModelFactory.NS + "A");
+        OntClass a = m.createOntClass(NS + "A");
         Assertions.assertTrue(a.superClass().isEmpty());
     }
 
@@ -452,7 +454,7 @@ public class OntClassSuperClassesTest {
     })
     public void testListSuperClasses7a(TestSpec spec) {
         OntModel m = OntModelFactory.createModel(spec.inst);
-        OntClass A = m.createOntClass(TestModelFactory.NS + "A");
+        OntClass A = m.createOntClass(NS + "A");
         A.addSuperClass(A);
 
         Assertions.assertTrue(A.superClasses(true).findFirst().isEmpty());
@@ -658,4 +660,194 @@ public class OntClassSuperClassesTest {
         Assertions.assertEquals(Set.of("D", "F", "Resource"), indirectE);
         Assertions.assertEquals(Set.of("D", "Resource"), indirectF);
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM",
+            "OWL2_MEM",
+            "OWL2_EL_MEM",
+            "OWL2_QL_MEM",
+            "OWL2_RL_MEM",
+            "OWL1_DL_MEM",
+            "OWL1_MEM",
+            "OWL1_LITE_MEM",
+            "RDFS_MEM",
+    })
+    public void testHasSuperClass1a(TestSpec spec) {
+        //     D
+        //    | \
+        // B  |  C
+        //  \ | /
+        //    A
+        OntModel m = 
TestModelFactory.createClassesDBCA(OntModelFactory.createModel(spec.inst));
+        OntClass A = m.createOntClass(NS + "A");
+        OntClass B = m.createOntClass(NS + "B");
+        OntClass C = m.createOntClass(NS + "C");
+        OntClass D = m.createOntClass(NS + "D");
+
+        Assertions.assertTrue(A.hasSuperClass(A, false));
+        Assertions.assertTrue(A.hasSuperClass(B, false));
+        Assertions.assertTrue(A.hasSuperClass(C, false));
+        Assertions.assertTrue(A.hasSuperClass(D, false));
+        Assertions.assertFalse(B.hasSuperClass(A, false));
+        Assertions.assertTrue(B.hasSuperClass(B, false));
+        Assertions.assertFalse(B.hasSuperClass(C, false));
+        Assertions.assertFalse(B.hasSuperClass(D, false));
+        Assertions.assertFalse(C.hasSuperClass(A, false));
+        Assertions.assertFalse(C.hasSuperClass(B, false));
+        Assertions.assertTrue(C.hasSuperClass(C, false));
+        Assertions.assertTrue(C.hasSuperClass(D, false));
+        Assertions.assertFalse(D.hasSuperClass(A, false));
+        Assertions.assertFalse(D.hasSuperClass(B, false));
+        Assertions.assertFalse(D.hasSuperClass(C, false));
+        Assertions.assertTrue(D.hasSuperClass(D, false));
+
+        Assertions.assertTrue(A.hasSuperClass(A, true));
+        Assertions.assertTrue(A.hasSuperClass(B, true));
+        Assertions.assertTrue(A.hasSuperClass(C, true));
+        Assertions.assertFalse(A.hasSuperClass(D, true));
+        Assertions.assertFalse(B.hasSuperClass(A, true));
+        Assertions.assertTrue(B.hasSuperClass(B, true));
+        Assertions.assertFalse(B.hasSuperClass(C, true));
+        Assertions.assertFalse(B.hasSuperClass(D, true));
+        Assertions.assertFalse(C.hasSuperClass(A, true));
+        Assertions.assertFalse(C.hasSuperClass(B, true));
+        Assertions.assertTrue(C.hasSuperClass(C, true));
+        Assertions.assertTrue(C.hasSuperClass(D, true));
+        Assertions.assertFalse(D.hasSuperClass(A, true));
+        Assertions.assertFalse(D.hasSuperClass(B, true));
+        Assertions.assertFalse(D.hasSuperClass(C, true));
+        Assertions.assertTrue(D.hasSuperClass(D, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_RDFS_BUILTIN_INF",
+            "OWL2_DL_MEM_RDFS_INF",
+            "OWL2_DL_MEM_RULES_INF",
+            "OWL2_MEM_RDFS_INF",
+            "OWL2_MEM_RULES_INF",
+            "OWL2_MEM_MINI_RULES_INF",
+            "OWL2_MEM_MICRO_RULES_INF",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_RULES_INF",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_RULES_INF",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_RULES_INF",
+            "OWL1_DL_MEM_RDFS_INF",
+            "OWL1_DL_MEM_RULES_INF",
+            "OWL1_MEM_RDFS_INF",
+            "OWL1_MEM_RULES_INF",
+            "OWL1_MEM_MINI_RULES_INF",
+            "OWL1_MEM_MICRO_RULES_INF",
+            "OWL1_LITE_MEM_RDFS_INF",
+            "OWL1_LITE_MEM_RULES_INF",
+            "RDFS_MEM_RDFS_INF",
+    })
+    public void testHasSuperClass1b(TestSpec spec) {
+        //     D
+        //    | \
+        // B  |  C
+        //  \ | /
+        //    A
+        OntModel m = 
TestModelFactory.createClassesDBCA(OntModelFactory.createModel(spec.inst));
+        OntClass A = m.createOntClass(NS + "A");
+        OntClass B = m.createOntClass(NS + "B");
+        OntClass C = m.createOntClass(NS + "C");
+        OntClass D = m.createOntClass(NS + "D");
+
+        Assertions.assertTrue(A.hasSuperClass(A, false));
+        Assertions.assertTrue(A.hasSuperClass(B, false));
+        Assertions.assertTrue(A.hasSuperClass(C, false));
+        Assertions.assertTrue(A.hasSuperClass(D, false));
+        Assertions.assertFalse(B.hasSuperClass(A, false));
+        Assertions.assertTrue(B.hasSuperClass(B, false));
+        Assertions.assertFalse(B.hasSuperClass(C, false));
+        Assertions.assertFalse(B.hasSuperClass(D, false));
+        Assertions.assertFalse(C.hasSuperClass(A, false));
+        Assertions.assertFalse(C.hasSuperClass(B, false));
+        Assertions.assertTrue(C.hasSuperClass(C, false));
+        Assertions.assertTrue(C.hasSuperClass(D, false));
+        Assertions.assertFalse(D.hasSuperClass(A, false));
+        Assertions.assertFalse(D.hasSuperClass(B, false));
+        Assertions.assertFalse(D.hasSuperClass(C, false));
+        Assertions.assertTrue(D.hasSuperClass(D, false));
+
+        Assertions.assertTrue(A.hasSuperClass(A, true));
+        Assertions.assertTrue(A.hasSuperClass(B, true));
+        Assertions.assertTrue(A.hasSuperClass(C, true));
+        Assertions.assertFalse(A.hasSuperClass(D, true));
+        Assertions.assertFalse(B.hasSuperClass(A, true));
+        Assertions.assertTrue(B.hasSuperClass(B, true));
+        Assertions.assertFalse(B.hasSuperClass(C, true));
+        Assertions.assertFalse(B.hasSuperClass(D, true));
+        Assertions.assertFalse(C.hasSuperClass(A, true));
+        Assertions.assertFalse(C.hasSuperClass(B, true));
+        Assertions.assertTrue(C.hasSuperClass(C, true));
+        Assertions.assertTrue(C.hasSuperClass(D, true));
+        Assertions.assertFalse(D.hasSuperClass(A, true));
+        Assertions.assertFalse(D.hasSuperClass(B, true));
+        Assertions.assertFalse(D.hasSuperClass(C, true));
+        Assertions.assertTrue(D.hasSuperClass(D, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_TRANS_INF",
+            "OWL2_MEM_TRANS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+            "OWL1_DL_MEM_TRANS_INF",
+            "OWL1_MEM_TRANS_INF",
+            "OWL1_LITE_MEM_TRANS_INF",
+            "RDFS_MEM_TRANS_INF",
+    })
+    public void testHasSuperClass1c(TestSpec spec) {
+        //     D
+        //    | \
+        // B  |  C
+        //  \ | /
+        //    A
+        OntModel m = 
TestModelFactory.createClassesDBCA(OntModelFactory.createModel(spec.inst));
+        OntClass A = m.createOntClass(NS + "A");
+        OntClass B = m.createOntClass(NS + "B");
+        OntClass C = m.createOntClass(NS + "C");
+        OntClass D = m.createOntClass(NS + "D");
+
+        Assertions.assertTrue(A.hasSuperClass(A, false));
+        Assertions.assertTrue(A.hasSuperClass(B, false));
+        Assertions.assertTrue(A.hasSuperClass(C, false));
+        Assertions.assertTrue(A.hasSuperClass(D, false));
+        Assertions.assertFalse(B.hasSuperClass(A, false));
+        Assertions.assertTrue(B.hasSuperClass(B, false));
+        Assertions.assertFalse(B.hasSuperClass(C, false));
+        Assertions.assertFalse(B.hasSuperClass(D, false));
+        Assertions.assertFalse(C.hasSuperClass(A, false));
+        Assertions.assertFalse(C.hasSuperClass(B, false));
+        Assertions.assertTrue(C.hasSuperClass(C, false));
+        Assertions.assertTrue(C.hasSuperClass(D, false));
+        Assertions.assertFalse(D.hasSuperClass(A, false));
+        Assertions.assertFalse(D.hasSuperClass(B, false));
+        Assertions.assertFalse(D.hasSuperClass(C, false));
+        Assertions.assertTrue(D.hasSuperClass(D, false));
+
+        Assertions.assertTrue(A.hasSuperClass(A, true));
+        Assertions.assertTrue(A.hasSuperClass(B, true));
+        Assertions.assertTrue(A.hasSuperClass(C, true));
+        Assertions.assertFalse(A.hasSuperClass(D, true));
+        Assertions.assertFalse(B.hasSuperClass(A, true));
+        Assertions.assertTrue(B.hasSuperClass(B, true));
+        Assertions.assertFalse(B.hasSuperClass(C, true));
+        Assertions.assertFalse(B.hasSuperClass(D, true));
+        Assertions.assertFalse(C.hasSuperClass(A, true));
+        Assertions.assertFalse(C.hasSuperClass(B, true));
+        Assertions.assertTrue(C.hasSuperClass(C, true));
+        Assertions.assertTrue(C.hasSuperClass(D, true));
+        Assertions.assertFalse(D.hasSuperClass(A, true));
+        Assertions.assertFalse(D.hasSuperClass(B, true));
+        Assertions.assertFalse(D.hasSuperClass(C, true));
+        Assertions.assertTrue(D.hasSuperClass(D, true));
+    }
 }
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntIndividualClassesTest.java
 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntIndividualClassesTest.java
index 466131f393..48dd130132 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntIndividualClassesTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntIndividualClassesTest.java
@@ -736,4 +736,261 @@ public class OntIndividualClassesTest {
         Assertions.assertEquals(MiscUtils.hashSetOf("A", "D"), directAD);
         Assertions.assertEquals(MiscUtils.hashSetOf("A", "D"), indirectAD);
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM",
+            "OWL2_MEM",
+            "OWL2_EL_MEM",
+            "OWL2_QL_MEM",
+            "OWL2_RL_MEM",
+            "OWL1_DL_MEM",
+            "OWL1_MEM",
+            "OWL1_LITE_MEM",
+            "RDFS_MEM",
+    })
+    public void testHasOntClasses1a(TestSpec spec) {
+        //  A   B
+        //  .\ /.
+        //  . C .
+        //  . | .
+        //  . D .
+        //  ./  .
+        //  A   .   E
+        //   \  .  |
+        //    \ . /
+        //      B
+        OntModel m = 
TestModelFactory.createClassesABCDAEB(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+
+        OntIndividual iAD = A.createIndividual(NS + "iAD");
+        iAD.attachClass(D);
+        OntIndividual iDB = D.createIndividual(NS + "iDB");
+        iDB.attachClass(B);
+        OntIndividual iC = C.createIndividual(NS + "iC");
+        OntIndividual iE = E.createIndividual(NS + "iE");
+
+        Assertions.assertTrue(iAD.hasOntClass(A, false));
+        Assertions.assertFalse(iDB.hasOntClass(A, false));
+        Assertions.assertFalse(iC.hasOntClass(A, false));
+        Assertions.assertFalse(iE.hasOntClass(A, false));
+        Assertions.assertFalse(iAD.hasOntClass(B, false));
+        Assertions.assertTrue(iDB.hasOntClass(B, false));
+        Assertions.assertFalse(iC.hasOntClass(B, false));
+        Assertions.assertFalse(iE.hasOntClass(B, false));
+        Assertions.assertFalse(iAD.hasOntClass(C, false));
+        Assertions.assertFalse(iDB.hasOntClass(C, false));
+        Assertions.assertTrue(iC.hasOntClass(C, false));
+        Assertions.assertFalse(iE.hasOntClass(C, false));
+        Assertions.assertTrue(iAD.hasOntClass(D, false));
+        Assertions.assertTrue(iDB.hasOntClass(D, false));
+        Assertions.assertFalse(iC.hasOntClass(D, false));
+        Assertions.assertFalse(iE.hasOntClass(D, false));
+        Assertions.assertFalse(iAD.hasOntClass(E, false));
+        Assertions.assertFalse(iDB.hasOntClass(E, false));
+        Assertions.assertFalse(iC.hasOntClass(E, false));
+        Assertions.assertTrue(iE.hasOntClass(E, false));
+
+        Assertions.assertTrue(iAD.hasOntClass(A, true));
+        Assertions.assertFalse(iDB.hasOntClass(A, true));
+        Assertions.assertFalse(iC.hasOntClass(A, true));
+        Assertions.assertFalse(iE.hasOntClass(A, true));
+        Assertions.assertFalse(iAD.hasOntClass(B, true));
+        Assertions.assertTrue(iDB.hasOntClass(B, true));
+        Assertions.assertFalse(iC.hasOntClass(B, true));
+        Assertions.assertFalse(iE.hasOntClass(B, true));
+        Assertions.assertFalse(iAD.hasOntClass(C, true));
+        Assertions.assertFalse(iDB.hasOntClass(C, true));
+        Assertions.assertTrue(iC.hasOntClass(C, true));
+        Assertions.assertFalse(iE.hasOntClass(C, true));
+        Assertions.assertFalse(iAD.hasOntClass(D, true));
+        Assertions.assertTrue(iDB.hasOntClass(D, true));
+        Assertions.assertFalse(iC.hasOntClass(D, true));
+        Assertions.assertFalse(iE.hasOntClass(D, true));
+        Assertions.assertFalse(iAD.hasOntClass(E, true));
+        Assertions.assertFalse(iDB.hasOntClass(E, true));
+        Assertions.assertFalse(iC.hasOntClass(E, true));
+        Assertions.assertTrue(iE.hasOntClass(E, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_RDFS_BUILTIN_INF",
+            "OWL2_DL_MEM_RDFS_INF",
+            "OWL2_DL_MEM_RULES_INF",
+            "OWL2_MEM_RDFS_INF",
+            "OWL2_MEM_RULES_INF",
+            "OWL2_MEM_MINI_RULES_INF",
+            "OWL2_MEM_MICRO_RULES_INF",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_RULES_INF",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_RULES_INF",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_RULES_INF",
+            "OWL1_DL_MEM_RDFS_INF",
+            "OWL1_DL_MEM_RULES_INF",
+            "OWL1_MEM_RDFS_INF",
+            "OWL1_MEM_RULES_INF",
+            "OWL1_MEM_MINI_RULES_INF",
+            "OWL1_MEM_MICRO_RULES_INF",
+            "OWL1_LITE_MEM_RDFS_INF",
+            "OWL1_LITE_MEM_RULES_INF",
+            "RDFS_MEM_RDFS_INF",
+    })
+    public void testHasOntClasses1b(TestSpec spec) {
+        //  A   B
+        //  .\ /.
+        //  . C .
+        //  . | .
+        //  . D .
+        //  ./  .
+        //  A   .   E
+        //   \  .  |
+        //    \ . /
+        //      B
+        OntModel m = 
TestModelFactory.createClassesABCDAEB(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+
+        OntIndividual iAD = A.createIndividual(NS + "iAD");
+        iAD.attachClass(D);
+        OntIndividual iDB = D.createIndividual(NS + "iDB");
+        iDB.attachClass(B);
+        OntIndividual iC = C.createIndividual(NS + "iC");
+        OntIndividual iE = E.createIndividual(NS + "iE");
+
+        Assertions.assertTrue(iAD.hasOntClass(A, false));
+        Assertions.assertTrue(iDB.hasOntClass(A, false));
+        Assertions.assertTrue(iC.hasOntClass(A, false));
+        Assertions.assertFalse(iE.hasOntClass(A, false));
+        Assertions.assertTrue(iAD.hasOntClass(B, false));
+        Assertions.assertTrue(iDB.hasOntClass(B, false));
+        Assertions.assertTrue(iC.hasOntClass(B, false));
+        Assertions.assertFalse(iE.hasOntClass(B, false));
+        Assertions.assertTrue(iAD.hasOntClass(C, false));
+        Assertions.assertTrue(iDB.hasOntClass(C, false));
+        Assertions.assertTrue(iC.hasOntClass(C, false));
+        Assertions.assertFalse(iE.hasOntClass(C, false));
+        Assertions.assertTrue(iAD.hasOntClass(D, false));
+        Assertions.assertTrue(iDB.hasOntClass(D, false));
+        Assertions.assertTrue(iC.hasOntClass(D, false));
+        Assertions.assertFalse(iE.hasOntClass(D, false));
+        Assertions.assertTrue(iAD.hasOntClass(E, false));
+        Assertions.assertTrue(iDB.hasOntClass(E, false));
+        Assertions.assertTrue(iC.hasOntClass(E, false));
+        Assertions.assertTrue(iE.hasOntClass(E, false));
+
+        Assertions.assertTrue(iAD.hasOntClass(A, true));
+        Assertions.assertTrue(iDB.hasOntClass(A, true));
+        Assertions.assertTrue(iC.hasOntClass(A, true));
+        Assertions.assertFalse(iE.hasOntClass(A, true));
+        Assertions.assertTrue(iAD.hasOntClass(B, true));
+        Assertions.assertTrue(iDB.hasOntClass(B, true));
+        Assertions.assertTrue(iC.hasOntClass(B, true));
+        Assertions.assertFalse(iE.hasOntClass(B, true));
+        Assertions.assertTrue(iAD.hasOntClass(C, true));
+        Assertions.assertTrue(iDB.hasOntClass(C, true));
+        Assertions.assertTrue(iC.hasOntClass(C, true));
+        Assertions.assertFalse(iE.hasOntClass(C, true));
+        Assertions.assertTrue(iAD.hasOntClass(D, true));
+        Assertions.assertTrue(iDB.hasOntClass(D, true));
+        Assertions.assertTrue(iC.hasOntClass(D, true));
+        Assertions.assertFalse(iE.hasOntClass(D, true));
+        Assertions.assertFalse(iAD.hasOntClass(E, true));
+        Assertions.assertFalse(iDB.hasOntClass(E, true));
+        Assertions.assertFalse(iC.hasOntClass(E, true));
+        Assertions.assertTrue(iE.hasOntClass(E, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_TRANS_INF",
+            "OWL2_MEM_TRANS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+            "OWL1_DL_MEM_TRANS_INF",
+            "OWL1_MEM_TRANS_INF",
+            "OWL1_LITE_MEM_TRANS_INF",
+            "RDFS_MEM_TRANS_INF",
+    })
+    public void testHasOntClasses1c(TestSpec spec) {
+        //  A   B
+        //  .\ /.
+        //  . C .
+        //  . | .
+        //  . D .
+        //  ./  .
+        //  A   .   E
+        //   \  .  |
+        //    \ . /
+        //      B
+        OntModel m = 
TestModelFactory.createClassesABCDAEB(OntModelFactory.createModel(spec.inst));
+
+        OntClass A = m.getOntClass(NS + "A");
+        OntClass B = m.getOntClass(NS + "B");
+        OntClass C = m.getOntClass(NS + "C");
+        OntClass D = m.getOntClass(NS + "D");
+        OntClass E = m.getOntClass(NS + "E");
+
+        OntIndividual iAD = A.createIndividual(NS + "iAD");
+        iAD.attachClass(D);
+        OntIndividual iDB = D.createIndividual(NS + "iDB");
+        iDB.attachClass(B);
+        OntIndividual iC = C.createIndividual(NS + "iC");
+        OntIndividual iE = E.createIndividual(NS + "iE");
+
+        Assertions.assertTrue(iAD.hasOntClass(A, false));
+        Assertions.assertFalse(iDB.hasOntClass(A, false));
+        Assertions.assertFalse(iC.hasOntClass(A, false));
+        Assertions.assertFalse(iE.hasOntClass(A, false));
+        Assertions.assertFalse(iAD.hasOntClass(B, false));
+        Assertions.assertTrue(iDB.hasOntClass(B, false));
+        Assertions.assertFalse(iC.hasOntClass(B, false));
+        Assertions.assertFalse(iE.hasOntClass(B, false));
+        Assertions.assertFalse(iAD.hasOntClass(C, false));
+        Assertions.assertFalse(iDB.hasOntClass(C, false));
+        Assertions.assertTrue(iC.hasOntClass(C, false));
+        Assertions.assertFalse(iE.hasOntClass(C, false));
+        Assertions.assertTrue(iAD.hasOntClass(D, false));
+        Assertions.assertTrue(iDB.hasOntClass(D, false));
+        Assertions.assertFalse(iC.hasOntClass(D, false));
+        Assertions.assertFalse(iE.hasOntClass(D, false));
+        Assertions.assertFalse(iAD.hasOntClass(E, false));
+        Assertions.assertFalse(iDB.hasOntClass(E, false));
+        Assertions.assertFalse(iC.hasOntClass(E, false));
+        Assertions.assertTrue(iE.hasOntClass(E, false));
+
+        Assertions.assertTrue(iAD.hasOntClass(A, true));
+        Assertions.assertFalse(iDB.hasOntClass(A, true));
+        Assertions.assertFalse(iC.hasOntClass(A, true));
+        Assertions.assertFalse(iE.hasOntClass(A, true));
+        Assertions.assertFalse(iAD.hasOntClass(B, true));
+        Assertions.assertTrue(iDB.hasOntClass(B, true));
+        Assertions.assertFalse(iC.hasOntClass(B, true));
+        Assertions.assertFalse(iE.hasOntClass(B, true));
+        Assertions.assertFalse(iAD.hasOntClass(C, true));
+        Assertions.assertFalse(iDB.hasOntClass(C, true));
+        Assertions.assertTrue(iC.hasOntClass(C, true));
+        Assertions.assertFalse(iE.hasOntClass(C, true));
+        Assertions.assertTrue(iAD.hasOntClass(D, true));
+        Assertions.assertTrue(iDB.hasOntClass(D, true));
+        Assertions.assertFalse(iC.hasOntClass(D, true));
+        Assertions.assertFalse(iE.hasOntClass(D, true));
+        Assertions.assertFalse(iAD.hasOntClass(E, true));
+        Assertions.assertFalse(iDB.hasOntClass(E, true));
+        Assertions.assertFalse(iC.hasOntClass(E, true));
+        Assertions.assertTrue(iE.hasOntClass(E, true));
+    }
+
 }
diff --git a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntListTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntListTest.java
index 052aa20783..0174523f28 100644
--- a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntListTest.java
+++ b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntListTest.java
@@ -337,7 +337,7 @@ public class OntListTest {
     public void testTypedList() {
         OntGraphModelImpl m = new OntGraphModelImpl(
                 
OntModelFactory.createUnionGraph(GraphMemFactory.createGraphMem()),
-                OntSpecification.OWL2_DL_MEM_BUILTIN_INF.getPersonality()
+                OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF.getPersonality()
         );
         m.setNsPrefixes(OntModelFactory.STANDARD);
         Resource a = m.createResource("A");
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelIndividualsTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelIndividualsTest.java
index 6fdfced1aa..e4a316d05a 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelIndividualsTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelIndividualsTest.java
@@ -42,8 +42,9 @@ import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.jena.ontapi.TestModelFactory.NS;
+
 public class OntModelIndividualsTest {
-    private static final String NS = "http://ex.com/testing/ontology#";;
 
     @ParameterizedTest
     @EnumSource(names = {
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
index 3309392eeb..1111eb3bc0 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2QLSpecTest.java
@@ -218,7 +218,7 @@ public class OntModelOWL2QLSpecTest {
         OntObjectProperty op = m.createObjectProperty("p");
         OntDataProperty dp = m.createDataProperty("d");
 
-        OntClass c0 = m.createOntClass("c");
+        OntClass c0 = m.createOntClass("c0");
         OntClass c1 = m.createDataSomeValuesFrom(dp, 
m.getDatatype(XSD.xstring.getURI()));
         OntClass c2 = m.createObjectSomeValuesFrom(op, c0);
         OntClass c3 = m.createObjectSomeValuesFrom(op, m.getOWLThing());
@@ -226,6 +226,7 @@ public class OntModelOWL2QLSpecTest {
         OntClass c5 = m.createObjectComplementOf(c1);
 
         c0.addProperty(RDFS.subClassOf, c4);
+        c4.addProperty(RDFS.subClassOf, c1);
         c4.addProperty(RDFS.subClassOf, c5);
         c3.addProperty(RDFS.subClassOf, c0);
         c2.addProperty(RDFS.subClassOf, c0);
@@ -233,7 +234,7 @@ public class OntModelOWL2QLSpecTest {
         Assertions.assertEquals(List.of(c3), 
c0.subClasses().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(c4), 
c0.superClasses().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(c0), 
c4.subClasses().collect(Collectors.toList()));
-        Assertions.assertEquals(List.of(c5), 
c4.superClasses().collect(Collectors.toList()));
+        Assertions.assertEquals(List.of(), 
c4.superClasses().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(), 
c5.subClasses().collect(Collectors.toList()));
 
         Assertions.assertThrows(OntJenaException.Unsupported.class, () -> 
c0.addSubClass(c2));
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
index 3dee2b20fb..cc94ffd89b 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntModelOWL2RLSpecTest.java
@@ -108,7 +108,7 @@ public class OntModelOWL2RLSpecTest {
         c1.addProperty(RDFS.subClassOf, c3);
 
         Assertions.assertEquals(0, c1.superClasses().count());
-        Assertions.assertEquals(List.of(c1), 
c3.subClasses().collect(Collectors.toList()));
+        Assertions.assertEquals(List.of(), 
c3.subClasses().collect(Collectors.toList()));
 
         c3.addProperty(RDFS.subClassOf, c2);
         Assertions.assertEquals(List.of(c2), 
c3.superClasses().collect(Collectors.toList()));
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntPropertyTest.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntPropertyTest.java
index ccbc4a029c..df360dabfa 100644
--- a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntPropertyTest.java
+++ b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntPropertyTest.java
@@ -38,6 +38,8 @@ import org.junit.jupiter.params.provider.EnumSource;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.jena.ontapi.TestModelFactory.NS;
+
 /**
  * Properties' generic test:
  * {@link OntNamedProperty},
@@ -55,7 +57,7 @@ public class OntPropertyTest {
     public void testCreateProperties() {
         String ns = "http://test.com/graph/7#";;
 
-        OntModel m = 
OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD).setNsPrefix("test",
 ns);
+        OntModel m = OntModelFactory.createModel().setNsPrefix("test", ns);
         OntAnnotationProperty a1 = m.createAnnotationProperty(ns + "a-p-1");
         OntAnnotationProperty a2 = m.createAnnotationProperty(ns + "a-p-2");
         m.createObjectProperty(ns + "o-p-1");
@@ -76,7 +78,7 @@ public class OntPropertyTest {
 
     @Test
     public void testListPropertyHierarchy() {
-        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF).setNsPrefixes(OntModelFactory.STANDARD);
+        OntModel m = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF);
         OntDataProperty da = m.createDataProperty("dA");
         OntDataProperty db = m.createDataProperty("dB");
 
@@ -98,7 +100,6 @@ public class OntPropertyTest {
         ab.addSuperProperty(ac).addSuperProperty(m.getRDFSComment());
         ac.addSuperProperty(aa);
 
-
         Assertions.assertEquals(1, da.superProperties(true).count());
         Assertions.assertEquals(2, da.superProperties(false).count());
 
@@ -114,7 +115,7 @@ public class OntPropertyTest {
 
     @Test
     public void testIndirectDomains() {
-        OntModel m = 
OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD).setNsPrefix("",
 "http://ex.com#";);
+        OntModel m = OntModelFactory.createModel().setNsPrefix("", 
"http://ex.com#";);
         OntObjectProperty hasDog = 
m.createObjectProperty(m.expandPrefix(":hasDog"));
         OntDataProperty hasName = 
m.createDataProperty(m.expandPrefix(":hasName"));
         OntClass animal = m.createOntClass(m.expandPrefix(":Animal"));
@@ -131,7 +132,7 @@ public class OntPropertyTest {
 
     @Test
     public void testReferringRestrictions() {
-        OntModel m = 
OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD);
+        OntModel m = OntModelFactory.createModel();
 
         OntObjectProperty p1 = m.createObjectProperty(":p1");
         OntObjectProperty p2 = m.createObjectProperty(":p2");
@@ -247,7 +248,7 @@ public class OntPropertyTest {
             "OWL1_MEM_TRANS_INF",
     })
     public void testListDeclaringClasses2b(TestSpec spec) {
-        OntModel m = 
OntModelFactory.createModel(spec.inst).setNsPrefixes(OntModelFactory.STANDARD);
+        OntModel m = OntModelFactory.createModel(spec.inst);
 
         OntClass c1 = m.createOntClass(":C1");
         OntClass c2 = m.createOntClass(":C2");
@@ -321,7 +322,7 @@ public class OntPropertyTest {
             "RDFS_MEM_TRANS_INF",
     })
     public void testListDeclaringClasses3a(TestSpec spec) {
-        OntModel m = 
OntModelFactory.createModel(spec.inst).setNsPrefixes(OntModelFactory.STANDARD);
+        OntModel m = OntModelFactory.createModel(spec.inst);
 
         Resource c1 = m.createOntClass(":C1");
         Resource c2 = m.createOntClass(":C2");
@@ -387,4 +388,212 @@ public class OntPropertyTest {
         Assertions.assertEquals(Set.of(c3, c4, c5, c6), 
p10.declaringClasses(true).collect(Collectors.toSet()));
         Assertions.assertEquals(Set.of(c1, c2, c3, c4, c5, c6), 
p10.declaringClasses(false).collect(Collectors.toSet()));
     }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM",
+            "OWL2_MEM",
+            "OWL2_EL_MEM",
+            "OWL2_QL_MEM",
+            "OWL2_RL_MEM",
+            "OWL1_DL_MEM",
+            "OWL1_MEM",
+            "OWL1_LITE_MEM",
+    })
+    public void testHasSubProperty1a(TestSpec spec) {
+        OntModel m = OntModelFactory.createModel(spec.inst);
+
+        OntObjectProperty p1 = m.createObjectProperty(NS + "p1");
+        OntProperty p2 = m.createObjectProperty(NS + "p2");
+        OntProperty p3 = m.createObjectProperty(NS + "p3");
+        OntDataProperty p4 = m.createDataProperty(NS + "p4");
+
+        p1.addProperty(RDFS.subPropertyOf, p2);
+        p2.addProperty(RDFS.subPropertyOf, p3);
+        p3.addProperty(RDFS.subPropertyOf, p4);
+
+        Assertions.assertTrue(p1.hasSubProperty(p1, false));
+        Assertions.assertFalse(p1.hasSubProperty(p2, false));
+        Assertions.assertFalse(p1.hasSubProperty(p3, false));
+        Assertions.assertFalse(p1.hasSubProperty(p4, false));
+        Assertions.assertTrue(p2.hasSubProperty(p1, false));
+        Assertions.assertTrue(p2.hasSubProperty(p2, false));
+        Assertions.assertFalse(p2.hasSubProperty(p3, false));
+        Assertions.assertFalse(p2.hasSubProperty(p4, false));
+        Assertions.assertFalse(p3.hasSubProperty(p1, false));
+        Assertions.assertTrue(p3.hasSubProperty(p2, false));
+        Assertions.assertTrue(p3.hasSubProperty(p3, false));
+        Assertions.assertFalse(p3.hasSubProperty(p4, false));
+        Assertions.assertFalse(p4.hasSubProperty(p1, false));
+        Assertions.assertFalse(p4.hasSubProperty(p2, false));
+        Assertions.assertFalse(p4.hasSubProperty(p3, false));
+        Assertions.assertTrue(p4.hasSubProperty(p4, false));
+
+        Assertions.assertTrue(p1.hasSubProperty(p1, true));
+        Assertions.assertFalse(p1.hasSubProperty(p2, true));
+        Assertions.assertFalse(p1.hasSubProperty(p3, true));
+        Assertions.assertFalse(p1.hasSubProperty(p4, true));
+        Assertions.assertTrue(p2.hasSubProperty(p1, true));
+        Assertions.assertTrue(p2.hasSubProperty(p2, true));
+        Assertions.assertFalse(p2.hasSubProperty(p3, true));
+        Assertions.assertFalse(p2.hasSubProperty(p4, true));
+        Assertions.assertFalse(p3.hasSubProperty(p1, true));
+        Assertions.assertTrue(p3.hasSubProperty(p2, true));
+        Assertions.assertTrue(p3.hasSubProperty(p3, true));
+        Assertions.assertFalse(p3.hasSubProperty(p4, true));
+        Assertions.assertFalse(p4.hasSubProperty(p1, true));
+        Assertions.assertFalse(p4.hasSubProperty(p2, true));
+        Assertions.assertFalse(p4.hasSubProperty(p3, true));
+        Assertions.assertTrue(p4.hasSubProperty(p4, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "OWL2_DL_MEM_RDFS_BUILTIN_INF",
+            "OWL2_DL_MEM_RDFS_INF",
+            "OWL2_DL_MEM_TRANS_INF",
+            "OWL2_DL_MEM_RULES_INF",
+            "OWL2_MEM_RDFS_INF",
+            "OWL2_MEM_TRANS_INF",
+            "OWL2_MEM_RULES_INF",
+            "OWL2_MEM_MINI_RULES_INF",
+            "OWL2_MEM_MICRO_RULES_INF",
+            "OWL2_EL_MEM_RDFS_INF",
+            "OWL2_EL_MEM_TRANS_INF",
+            "OWL2_EL_MEM_RULES_INF",
+            "OWL2_QL_MEM_RDFS_INF",
+            "OWL2_QL_MEM_TRANS_INF",
+            "OWL2_QL_MEM_RULES_INF",
+            "OWL2_RL_MEM_RDFS_INF",
+            "OWL2_RL_MEM_TRANS_INF",
+            "OWL2_RL_MEM_RULES_INF",
+            "OWL1_DL_MEM_RDFS_INF",
+            "OWL1_DL_MEM_TRANS_INF",
+            "OWL1_DL_MEM_RULES_INF",
+            "OWL1_MEM_RDFS_INF",
+            "OWL1_MEM_TRANS_INF",
+            "OWL1_MEM_RULES_INF",
+            "OWL1_MEM_MINI_RULES_INF",
+            "OWL1_MEM_MICRO_RULES_INF",
+            "OWL1_LITE_MEM_RDFS_INF",
+            "OWL1_LITE_MEM_TRANS_INF",
+            "OWL1_LITE_MEM_RULES_INF",
+    })
+    public void testHasSubProperty1b(TestSpec spec) {
+        OntModel m = OntModelFactory.createModel(spec.inst);
+
+        OntObjectProperty p1 = m.createObjectProperty(NS + "p1");
+        OntProperty p2 = m.createObjectProperty(NS + "p2");
+        OntProperty p3 = m.createObjectProperty(NS + "p3");
+        OntDataProperty p4 = m.createDataProperty(NS + "p4");
+
+        p1.addProperty(RDFS.subPropertyOf, p2);
+        p2.addProperty(RDFS.subPropertyOf, p3);
+        p3.addProperty(RDFS.subPropertyOf, p4);
+
+        Assertions.assertTrue(p1.hasSubProperty(p1, false));
+        Assertions.assertFalse(p1.hasSubProperty(p2, false));
+        Assertions.assertFalse(p1.hasSubProperty(p3, false));
+        Assertions.assertFalse(p1.hasSubProperty(p4, false));
+        Assertions.assertTrue(p2.hasSubProperty(p1, false));
+        Assertions.assertTrue(p2.hasSubProperty(p2, false));
+        Assertions.assertFalse(p2.hasSubProperty(p3, false));
+        Assertions.assertFalse(p2.hasSubProperty(p4, false));
+        Assertions.assertTrue(p3.hasSubProperty(p1, false));
+        Assertions.assertTrue(p3.hasSubProperty(p2, false));
+        Assertions.assertTrue(p3.hasSubProperty(p3, false));
+        Assertions.assertFalse(p3.hasSubProperty(p4, false));
+        Assertions.assertFalse(p4.hasSubProperty(p1, false));
+        Assertions.assertFalse(p4.hasSubProperty(p2, false));
+        Assertions.assertFalse(p4.hasSubProperty(p3, false));
+        Assertions.assertTrue(p4.hasSubProperty(p4, false));
+
+        Assertions.assertTrue(p1.hasSubProperty(p1, true));
+        Assertions.assertFalse(p1.hasSubProperty(p2, true));
+        Assertions.assertFalse(p1.hasSubProperty(p3, true));
+        Assertions.assertFalse(p1.hasSubProperty(p4, true));
+        Assertions.assertTrue(p2.hasSubProperty(p1, true));
+        Assertions.assertTrue(p2.hasSubProperty(p2, true));
+        Assertions.assertFalse(p2.hasSubProperty(p3, true));
+        Assertions.assertFalse(p2.hasSubProperty(p4, true));
+        Assertions.assertFalse(p3.hasSubProperty(p1, true));
+        Assertions.assertTrue(p3.hasSubProperty(p2, true));
+        Assertions.assertTrue(p3.hasSubProperty(p3, true));
+        Assertions.assertFalse(p3.hasSubProperty(p4, true));
+        Assertions.assertFalse(p4.hasSubProperty(p1, true));
+        Assertions.assertFalse(p4.hasSubProperty(p2, true));
+        Assertions.assertFalse(p4.hasSubProperty(p3, true));
+        Assertions.assertTrue(p4.hasSubProperty(p4, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "RDFS_MEM",
+    })
+    public void testHasSuperProperty1a(TestSpec spec) {
+        OntModel m = OntModelFactory.createModel(spec.inst);
+
+        OntProperty p1 = m.createRDFProperty(NS + "p1");
+        OntProperty p2 = m.createRDFProperty(NS + "p2");
+        OntProperty p3 = m.createRDFProperty(NS + "p3");
+
+        p1.addProperty(RDFS.subPropertyOf, p2);
+        p2.addProperty(RDFS.subPropertyOf, p3);
+
+        Assertions.assertTrue(p1.hasSuperProperty(p1, false));
+        Assertions.assertTrue(p1.hasSuperProperty(p2, false));
+        Assertions.assertFalse(p1.hasSuperProperty(p3, false));
+        Assertions.assertFalse(p2.hasSuperProperty(p1, false));
+        Assertions.assertTrue(p2.hasSuperProperty(p2, false));
+        Assertions.assertTrue(p2.hasSuperProperty(p3, false));
+        Assertions.assertFalse(p3.hasSuperProperty(p1, false));
+        Assertions.assertFalse(p3.hasSuperProperty(p2, false));
+        Assertions.assertTrue(p3.hasSuperProperty(p3, false));
+
+        Assertions.assertTrue(p1.hasSuperProperty(p1, true));
+        Assertions.assertTrue(p1.hasSuperProperty(p2, true));
+        Assertions.assertFalse(p1.hasSuperProperty(p3, true));
+        Assertions.assertFalse(p2.hasSuperProperty(p1, true));
+        Assertions.assertTrue(p2.hasSuperProperty(p2, true));
+        Assertions.assertTrue(p2.hasSuperProperty(p3, true));
+        Assertions.assertFalse(p3.hasSuperProperty(p1, true));
+        Assertions.assertFalse(p3.hasSuperProperty(p2, true));
+        Assertions.assertTrue(p3.hasSuperProperty(p3, true));
+    }
+
+    @ParameterizedTest
+    @EnumSource(names = {
+            "RDFS_MEM_RDFS_INF",
+            "RDFS_MEM_TRANS_INF",
+    })
+    public void testHasSuperProperty1b(TestSpec spec) {
+        OntModel m = OntModelFactory.createModel(spec.inst);
+
+        OntProperty p1 = m.createRDFProperty(NS + "p1");
+        OntProperty p2 = m.createRDFProperty(NS + "p2");
+        OntProperty p3 = m.createRDFProperty(NS + "p3");
+
+        p1.addProperty(RDFS.subPropertyOf, p2);
+        p2.addProperty(RDFS.subPropertyOf, p3);
+
+        Assertions.assertTrue(p1.hasSuperProperty(p1, false));
+        Assertions.assertTrue(p1.hasSuperProperty(p2, false));
+        Assertions.assertTrue(p1.hasSuperProperty(p3, false));
+        Assertions.assertFalse(p2.hasSuperProperty(p1, false));
+        Assertions.assertTrue(p2.hasSuperProperty(p2, false));
+        Assertions.assertTrue(p2.hasSuperProperty(p3, false));
+        Assertions.assertFalse(p3.hasSuperProperty(p1, false));
+        Assertions.assertFalse(p3.hasSuperProperty(p2, false));
+        Assertions.assertTrue(p3.hasSuperProperty(p3, false));
+
+        Assertions.assertTrue(p1.hasSuperProperty(p1, true));
+        Assertions.assertTrue(p1.hasSuperProperty(p2, true));
+        Assertions.assertFalse(p1.hasSuperProperty(p3, true));
+        Assertions.assertFalse(p2.hasSuperProperty(p1, true));
+        Assertions.assertTrue(p2.hasSuperProperty(p2, true));
+        Assertions.assertTrue(p2.hasSuperProperty(p3, true));
+        Assertions.assertFalse(p3.hasSuperProperty(p1, true));
+        Assertions.assertFalse(p3.hasSuperProperty(p2, true));
+        Assertions.assertTrue(p3.hasSuperProperty(p3, true));
+    }
 }
diff --git 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntUnionGraphRepositoryTest.java
 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntUnionGraphRepositoryTest.java
index 0b65709d05..2e95799810 100644
--- 
a/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntUnionGraphRepositoryTest.java
+++ 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/OntUnionGraphRepositoryTest.java
@@ -231,7 +231,7 @@ public class OntUnionGraphRepositoryTest {
 
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
 
-        OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
 
         Assertions.assertEquals(5, repository.count());
         Assertions.assertEquals(
@@ -261,7 +261,7 @@ public class OntUnionGraphRepositoryTest {
 
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
 
-        OntModelFactory.createModel(c.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModelFactory.createModel(c.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
 
         Assertions.assertEquals(5, repository.count());
         Assertions.assertEquals(
@@ -297,14 +297,14 @@ public class OntUnionGraphRepositoryTest {
     @Test
     public void testAddImportModel1() {
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
-        OntModel a = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF, 
repository).setID("A").getModel();
+        OntModel a = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, 
repository).setID("A").getModel();
 
         Assertions.assertEquals(List.of("A"), 
repository.ids().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(a.getGraph()), 
repository.graphs().collect(Collectors.toList()));
 
         a.createOntClass("FromA");
 
-        OntModel b = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF, 
repository);
+        OntModel b = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, 
repository);
         b.createOntClass("FromB");
 
         b.addImport(a);
@@ -340,7 +340,7 @@ public class OntUnionGraphRepositoryTest {
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
         Model data = ModelFactory.createDefaultModel();
         data.createResource("A", OWL2.Ontology);
-        OntModel a = OntModelFactory.createModel(data.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModel a = OntModelFactory.createModel(data.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
 
         Assertions.assertEquals(List.of("A"), 
repository.ids().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(a.getGraph()), 
repository.graphs().collect(Collectors.toList()));
@@ -381,7 +381,7 @@ public class OntUnionGraphRepositoryTest {
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
         Model data = ModelFactory.createDefaultModel();
         data.createResource("A", OWL2.Ontology);
-        OntModel a = OntModelFactory.createModel(data.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModel a = OntModelFactory.createModel(data.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
 
         Assertions.assertEquals(List.of("A"), 
repository.ids().collect(Collectors.toList()));
         Assertions.assertEquals(List.of(a.getGraph()), 
repository.graphs().collect(Collectors.toList()));
@@ -406,7 +406,7 @@ public class OntUnionGraphRepositoryTest {
     @Test
     public void testAddImportStatement() {
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
-        OntModel a = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_INF, 
repository);
+        OntModel a = 
OntModelFactory.createModel(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, 
repository);
         UnionGraph ag = (UnionGraph) a.getGraph();
 
         Model b = OntModelFactory.createDefaultModel();
@@ -482,7 +482,7 @@ public class OntUnionGraphRepositoryTest {
         a.addImport(b);
 
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
-        OntModel A = OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModel A = OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
         Assertions.assertEquals(3, A.size());
         Assertions.assertEquals(List.of("A", "B"), 
repository.ids().sorted().collect(Collectors.toList()));
 
@@ -585,7 +585,7 @@ public class OntUnionGraphRepositoryTest {
         OntModel b = OntModelFactory.createModel().setID("B").getModel();
 
         GraphRepository repository = 
GraphRepository.createGraphDocumentRepositoryMem();
-        OntModel A = OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_INF, repository);
+        OntModel A = OntModelFactory.createModel(a.getGraph(), 
OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF, repository);
         A.addImport(b);
         Assertions.assertEquals(List.of("A", "B"), 
repository.ids().sorted().collect(Collectors.toList()));
         
Assertions.assertNotNull(OntModelFactory.getModelOrNull(NodeFactory.createURI("A"),
 OntSpecification.OWL2_DL_MEM_TRANS_INF, repository));
diff --git a/jena-ontapi/src/test/java/org/apache/jena/ontapi/TestSpec.java 
b/jena-ontapi/src/test/java/org/apache/jena/ontapi/TestSpec.java
index d328055987..40311c1749 100644
--- a/jena-ontapi/src/test/java/org/apache/jena/ontapi/TestSpec.java
+++ b/jena-ontapi/src/test/java/org/apache/jena/ontapi/TestSpec.java
@@ -71,7 +71,7 @@ public enum TestSpec {
     OWL2_MEM_MINI_RULES_INF(OntSpecification.OWL2_FULL_MEM_MINI_RULES_INF),
     OWL2_MEM_MICRO_RULES_INF(OntSpecification.OWL2_FULL_MEM_MICRO_RULES_INF),
 
-    OWL2_DL_MEM_RDFS_BUILTIN_INF(OntSpecification.OWL2_DL_MEM_BUILTIN_INF),
+    
OWL2_DL_MEM_RDFS_BUILTIN_INF(OntSpecification.OWL2_DL_MEM_BUILTIN_RDFS_INF),
     OWL2_DL_MEM(OntSpecification.OWL2_DL_MEM),
     OWL2_DL_MEM_RDFS_INF(OntSpecification.OWL2_DL_MEM_RDFS_INF),
     OWL2_DL_MEM_TRANS_INF(OntSpecification.OWL2_DL_MEM_TRANS_INF),

Reply via email to