tag:rdf4j.org,2023:config/shacl.includeInferredStatements
+ */
+ public final static IRI includeInferredStatements = createIRI(NAMESPACE,
+ "shacl.includeInferredStatements");
+
/**
* tag:rdf4j.org,2023:config/shacl.performanceLogging
*/
diff --git a/core/model-vocabulary/src/main/java/org/eclipse/rdf4j/model/vocabulary/RSX.java b/core/model-vocabulary/src/main/java/org/eclipse/rdf4j/model/vocabulary/RSX.java
index 113f3083eeb..dafe56b5f24 100644
--- a/core/model-vocabulary/src/main/java/org/eclipse/rdf4j/model/vocabulary/RSX.java
+++ b/core/model-vocabulary/src/main/java/org/eclipse/rdf4j/model/vocabulary/RSX.java
@@ -40,6 +40,9 @@ public class RSX {
/** http://rdf4j.org/shacl-extensions#targetShape */
public final static IRI targetShape = create("targetShape");
+ public final static IRI rdfsSubClassReasoning = create("rdfsSubClassReasoning");
+ public final static IRI includeInferredStatements = create("includeInferredStatements");
+
public final static IRI dataGraph = create("dataGraph");
public final static IRI shapesGraph = create("shapesGraph");
diff --git a/core/sail/inferencer/src/main/java/org/eclipse/rdf4j/sail/inferencer/fc/SchemaCachingRDFSInferencerConnection.java b/core/sail/inferencer/src/main/java/org/eclipse/rdf4j/sail/inferencer/fc/SchemaCachingRDFSInferencerConnection.java
index 95b1df1e955..3a9bd33a2b7 100644
--- a/core/sail/inferencer/src/main/java/org/eclipse/rdf4j/sail/inferencer/fc/SchemaCachingRDFSInferencerConnection.java
+++ b/core/sail/inferencer/src/main/java/org/eclipse/rdf4j/sail/inferencer/fc/SchemaCachingRDFSInferencerConnection.java
@@ -114,7 +114,7 @@ void processForSchemaCache(Statement statement) {
sail.addSubPropertyOfStatement(
sail.getValueFactory().createStatement(subject, RDFS.SUBPROPERTYOF, RDFS.MEMBER));
schemaChange = true;
- } else if (predicate.equals(RDF.TYPE)) {
+ } else if (predicate.equals(RDF.TYPE) && object instanceof Resource) {
if (!sail.hasType(((Resource) object))) {
sail.addType((Resource) object);
schemaChange = true;
@@ -276,11 +276,7 @@ private void addStatement(boolean actuallyAdd, Resource subject, IRI predicate,
}
- if (predicate.equals(RDF.TYPE)) {
- if (!(object instanceof Resource)) {
- throw new SailException("Expected object to a a Resource: " + object.toString());
- }
-
+ if (predicate.equals(RDF.TYPE) && object instanceof Resource) {
sail.resolveTypes((Resource) object)
.stream()
.peek(inferredType -> {
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
index cc43e3e6015..dbab12bc961 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailBaseConfiguration.java
@@ -35,6 +35,7 @@ abstract class ShaclSailBaseConfiguration extends NotifyingSailWrapper {
private boolean validationEnabled = ShaclSailConfig.VALIDATION_ENABLED_DEFAULT;
private boolean cacheSelectNodes = ShaclSailConfig.CACHE_SELECT_NODES_DEFAULT;
private boolean rdfsSubClassReasoning = ShaclSailConfig.RDFS_SUB_CLASS_REASONING_DEFAULT;
+ private boolean includeInferredStatements = true;
private boolean serializableValidation = ShaclSailConfig.SERIALIZABLE_VALIDATION_DEFAULT;
private boolean performanceLogging = ShaclSailConfig.PERFORMANCE_LOGGING_DEFAULT;
private boolean eclipseRdf4jShaclExtensions = ShaclSailConfig.ECLIPSE_RDF4J_SHACL_EXTENSIONS_DEFAULT;
@@ -146,6 +147,25 @@ public void setRdfsSubClassReasoning(boolean rdfsSubClassReasoning) {
this.rdfsSubClassReasoning = rdfsSubClassReasoning;
}
+ /**
+ * Check if inferred statements from the base sail should be used during SHACL validation when
+ * {@link #isRdfsSubClassReasoning()} is disabled.
+ *
+ * @return true if inferred statements should be considered, false otherwise.
+ */
+ public boolean isIncludeInferredStatements() {
+ return includeInferredStatements;
+ }
+
+ /**
+ * Allow SHACL validation to use inferred statements from the base sail when RDFS subclass reasoning is disabled.
+ *
+ * @param includeInferredStatements default true
+ */
+ public void setIncludeInferredStatements(boolean includeInferredStatements) {
+ this.includeInferredStatements = includeInferredStatements;
+ }
+
/**
* Disable the SHACL validation on commit()
*/
diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
index c8c6db97dcb..01b7ac82dd9 100644
--- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
+++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java
@@ -51,6 +51,7 @@
import org.eclipse.rdf4j.sail.memory.MemoryStore;
import org.eclipse.rdf4j.sail.shacl.ShaclSail.TransactionSettings.ValidationApproach;
import org.eclipse.rdf4j.sail.shacl.ast.ContextWithShape;
+import org.eclipse.rdf4j.sail.shacl.ast.Shape;
import org.eclipse.rdf4j.sail.shacl.results.ValidationReport;
import org.eclipse.rdf4j.sail.shacl.results.lazy.LazyValidationReport;
import org.eclipse.rdf4j.sail.shacl.results.lazy.ValidationResultIterator;
@@ -76,11 +77,25 @@ public class ShaclSailConnection extends NotifyingSailConnectionWrapper implemen
Sail addedStatements;
Sail removedStatements;
+ Sail addedStatementsInferred;
+ Sail removedStatementsInferred;
+ Sail addedStatementsRdfsInferred;
+ Sail removedStatementsRdfsInferred;
+ Sail addedStatementsWithInferred;
+ Sail removedStatementsWithInferred;
+ Sail addedStatementsWithRdfsInferred;
+ Sail removedStatementsWithRdfsInferred;
+ Sail addedStatementsWithInferredAndRdfs;
+ Sail removedStatementsWithInferredAndRdfs;
private final HashSet