diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java index 125ef5a8b4f..9c6943eb29b 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/NodeShape.java @@ -7,6 +7,8 @@ ******************************************************************************/ package org.eclipse.rdf4j.sail.shacl.ast; +import java.util.Collection; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -230,41 +232,16 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - boolean isFilterCondition = constraintComponents.stream() - .map(o -> o.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, + List sparqlFragments = constraintComponents.stream() + .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, Scope.nodeShape)) - .map(SparqlFragment::isFilterCondition) - .findFirst() - .orElse(false); - - if (isFilterCondition) { - String sparql = constraintComponents.stream() - .map(c -> c.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, - Scope.nodeShape)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) && ( ", "( ", " )")); - - return SparqlFragment.filterCondition(sparql); + .collect(Collectors.toList()); + if (SparqlFragment.isFilterCondition(sparqlFragments)) { + return SparqlFragment.and(sparqlFragments); } else { - String sparql = constraintComponents.stream() - .map(c -> c.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, - Scope.nodeShape)) - .map(SparqlFragment::getFragment) - .reduce((a, b) -> a + "\n" + b) - .orElse(""); - return SparqlFragment.bgp(sparql); + return SparqlFragment.join(sparqlFragments); } } - @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - - return constraintComponents.stream() - .flatMap(c -> c.getStatementMatchers_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, Scope.nodeShape)); - - } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java index c27ae46503e..48787d6d06f 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java @@ -7,6 +7,7 @@ ******************************************************************************/ package org.eclipse.rdf4j.sail.shacl.ast; +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.UUID; @@ -279,47 +280,17 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - StatementMatcher.Variable someObject = new StatementMatcher.Variable( - UUID.randomUUID().toString().replace("-", "")); - - boolean isFilterCondition = constraintComponents.stream() - .map(o -> o.buildSparqlValidNodes_rsx_targetShape(object, someObject, rdfsSubClassOfReasoner, - Scope.propertyShape)) - .map(SparqlFragment::isFilterCondition) - .findFirst() - .orElse(false); - - if (isFilterCondition) { - String sparql = constraintComponents.stream() - .map(c -> c.buildSparqlValidNodes_rsx_targetShape(object, someObject, rdfsSubClassOfReasoner, - Scope.propertyShape)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) && ( ", "( ", " )")); - - return SparqlFragment.filterCondition(sparql); + List sparqlFragments = constraintComponents.stream() + .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(object, + StatementMatcher.Variable.getRandomInstance(), rdfsSubClassOfReasoner, Scope.propertyShape)) + .collect(Collectors.toList()); + if (SparqlFragment.isFilterCondition(sparqlFragments)) { + return SparqlFragment.and(sparqlFragments); } else { - String sparql = constraintComponents.stream() - .map(c -> c.buildSparqlValidNodes_rsx_targetShape(object, someObject, rdfsSubClassOfReasoner, - Scope.propertyShape)) - .map(SparqlFragment::getFragment) - .reduce((a, b) -> a + "\n" + b) - .orElse(""); - return SparqlFragment.bgp(sparql); + return SparqlFragment.join(sparqlFragments); } } - @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - StatementMatcher.Variable someObject = new StatementMatcher.Variable( - UUID.randomUUID().toString().replace("-", "")); - - return constraintComponents.stream() - .flatMap(c -> c.getStatementMatchers_rsx_targetShape(object, someObject, rdfsSubClassOfReasoner, - Scope.propertyShape)); - } - } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java index 5bdef2bad88..28ce33f9097 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/Shape.java @@ -264,26 +264,6 @@ List getConstraintComponents(ShaclProperties properties, Re properties.getIgnoredProperties())); } - properties.getOr() - .stream() - .map(or -> new OrConstraintComponent(or, connection, cache, shaclSail)) - .forEach(constraintComponent::add); - - properties.getXone() - .stream() - .map(xone -> new XoneConstraintComponent(xone, connection, cache, shaclSail)) - .forEach(constraintComponent::add); - - properties.getAnd() - .stream() - .map(and -> new AndConstraintComponent(and, connection, cache, shaclSail)) - .forEach(constraintComponent::add); - - properties.getNot() - .stream() - .map(or -> new NotConstraintComponent(or, connection, cache, shaclSail)) - .forEach(constraintComponent::add); - properties.getClazz() .stream() .map(ClassConstraintComponent::new) @@ -338,6 +318,26 @@ List getConstraintComponents(ShaclProperties properties, Re .forEach(constraintComponent::add); } + properties.getOr() + .stream() + .map(or -> new OrConstraintComponent(or, connection, cache, shaclSail)) + .forEach(constraintComponent::add); + + properties.getXone() + .stream() + .map(xone -> new XoneConstraintComponent(xone, connection, cache, shaclSail)) + .forEach(constraintComponent::add); + + properties.getAnd() + .stream() + .map(and -> new AndConstraintComponent(and, connection, cache, shaclSail)) + .forEach(constraintComponent::add); + + properties.getNot() + .stream() + .map(or -> new NotConstraintComponent(or, connection, cache, shaclSail)) + .forEach(constraintComponent::add); + return constraintComponent; } @@ -423,17 +423,6 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var throw new UnsupportedOperationException(this.getClass().getSimpleName()); } - /** - * For rsx:targetShape - * - * @return - */ - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - throw new UnsupportedOperationException(this.getClass().getSimpleName()); - } - public static class Factory { public static List getShapes(RepositoryConnection connection, ShaclSail shaclSail) { diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/SparqlFragment.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/SparqlFragment.java index 800eb5624ba..91cc3a19133 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/SparqlFragment.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/SparqlFragment.java @@ -7,29 +7,181 @@ ******************************************************************************/ package org.eclipse.rdf4j.sail.shacl.ast; +import static org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.AbstractConstraintComponent.VALUES_INJECTION_POINT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + public class SparqlFragment { - String fragment; - boolean filterCondition; - boolean bgp; + final static Pattern REGEX_INDENT = Pattern.compile("(?m)^"); + + private final String fragment; + private final List unionFragments = new ArrayList<>(); + + private boolean filterCondition; + private boolean bgp; + private boolean union; + + // This is currently experimental! + private static final boolean USE_UNION_PRESERVING_JOIN = false; + + private final List statementMatchers = new ArrayList<>(); - public SparqlFragment(String fragment) { + private SparqlFragment(List unionFragments, List statementMatchers) { + this.fragment = null; + this.unionFragments.addAll(unionFragments); + this.union = true; + this.statementMatchers.addAll(statementMatchers); + } + + private SparqlFragment(String fragment, boolean filterCondition, boolean bgp, + List statementMatchers) { this.fragment = fragment; + this.filterCondition = filterCondition; + this.bgp = bgp; + this.statementMatchers.addAll(statementMatchers); + + assert filterCondition != bgp; } - public static SparqlFragment filterCondition(String fragment) { - SparqlFragment sparqlFragment = new SparqlFragment(fragment); - sparqlFragment.filterCondition = true; - return sparqlFragment; + public static SparqlFragment filterCondition(String fragment, List statementMatchers) { + return new SparqlFragment(fragment, true, false, statementMatchers); } - public static SparqlFragment bgp(String fragment) { - SparqlFragment sparqlFragment = new SparqlFragment(fragment); - sparqlFragment.bgp = true; - return sparqlFragment; + public static SparqlFragment bgp(String fragment, List statementMatchers) { + return new SparqlFragment(fragment, false, true, statementMatchers); + } + + public static SparqlFragment and(List sparqlFragments) { + String collect = sparqlFragments.stream() + .peek(s -> { + assert s.filterCondition; + }) + .map(SparqlFragment::getFragment) + .collect(Collectors.joining(" ) && ( ", "( ", + " )")); + + return filterCondition(collect, + getStatementMatchers(sparqlFragments)); + } + + public static SparqlFragment or(List sparqlFragments) { + String collect = sparqlFragments.stream() + .peek(s -> { + assert s.filterCondition; + }) + .map(SparqlFragment::getFragment) + .collect(Collectors.joining(" ) || ( ", "( ", + " )")); + + return filterCondition(collect, + getStatementMatchers(sparqlFragments)); + } + + public static SparqlFragment join(List sparqlFragments) { + + if (USE_UNION_PRESERVING_JOIN && sparqlFragments.stream().anyMatch(s1 -> s1.union)) { + return unionPreservingJoin(sparqlFragments); + + } else { + String collect = sparqlFragments.stream() + .peek(s -> { + assert !s.filterCondition; + }) + .map(SparqlFragment::getFragment) + .map(SparqlFragment::indent) + .reduce((a, b) -> a + " \n " + b) + .orElse(""); + + return bgp(collect, getStatementMatchers(sparqlFragments)); + } + } + + private static SparqlFragment unionPreservingJoin(List sparqlFragments) { + List workingSet = new ArrayList<>(); + SparqlFragment firstSparqlFragment = sparqlFragments.get(0); + if (firstSparqlFragment.union) { + workingSet.addAll(firstSparqlFragment.unionFragments); + } else { + assert firstSparqlFragment.bgp; + workingSet.add(firstSparqlFragment.fragment); + } + + for (int i = 1; i < sparqlFragments.size(); i++) { + SparqlFragment sparqlFragment = sparqlFragments.get(i); + if (sparqlFragment.union) { + + List newWorkingSet = new ArrayList<>(); + + for (String unionFragment : sparqlFragment.unionFragments) { + for (String workingSetFragment : workingSet) { + newWorkingSet.add(workingSetFragment + "\n" + unionFragment); + } + } + + workingSet = newWorkingSet; + + } else { + assert sparqlFragment.bgp; + workingSet = workingSet + .stream() + .map(s -> sparqlFragment.fragment + "\n" + s) + .collect(Collectors.toList()); + + } + } + + SparqlFragment union = union(workingSet.toArray(new String[0])); + union.addStatementMatchers(getStatementMatchers(sparqlFragments)); + return union; + } + + public static boolean isFilterCondition(List sparqlFragments) { + boolean isFilterCondtion = sparqlFragments + .stream() + .anyMatch(SparqlFragment::isFilterCondition); + + assert !isFilterCondtion || sparqlFragments.stream().allMatch(SparqlFragment::isFilterCondition); + + return isFilterCondtion; + } + + public static SparqlFragment union(List sparqlFragments) { + List sparqlFragmentString = sparqlFragments + .stream() + .map(SparqlFragment::getFragment) + .collect(Collectors.toList()); + + return new SparqlFragment(sparqlFragmentString, getStatementMatchers(sparqlFragments)); + } + + public static List getStatementMatchers(List sparqlFragments) { + return sparqlFragments + .stream() + .flatMap(s -> s.statementMatchers.stream()) + .collect(Collectors.toList()); + } + + public static SparqlFragment union(String... query) { + return new SparqlFragment(Arrays.asList(query), Collections.emptyList()); } public String getFragment() { + if (union) { + return unionFragments.stream() + .map(SparqlFragment::indent) + .collect( + Collectors.joining( + "\n} UNION {\n" + VALUES_INJECTION_POINT + "\n", + "{\n" + VALUES_INJECTION_POINT + "\n", + "\n}")); + } + return fragment; } @@ -37,7 +189,15 @@ public boolean isFilterCondition() { return filterCondition; } - public boolean isBgp() { - return bgp; + public List getStatementMatchers() { + return statementMatchers; + } + + public void addStatementMatchers(List statementMatchers) { + this.statementMatchers.addAll(statementMatchers); + } + + public static String indent(String toIndent) { + return REGEX_INDENT.matcher(toIndent).replaceAll("\t"); } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java index e00622cd4c7..49da4b5284e 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/StatementMatcher.java @@ -7,8 +7,10 @@ ******************************************************************************/ package org.eclipse.rdf4j.sail.shacl.ast; +import java.util.List; import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Resource; @@ -44,6 +46,72 @@ public StatementMatcher(Variable subject, Variable predicate, Variable object) { this.objectValue = object == null ? null : object.value; } + public static List reduce(List statementMatchers) { + List wildcardMatchers = statementMatchers.stream() + .filter(s -> s.subjectIsWildcard() || s.predicateIsWildcard() || s.objectIsWildcard()) + .collect(Collectors.toList()); + + if (wildcardMatchers.isEmpty()) { + return statementMatchers; + } + + return statementMatchers.stream().filter(s -> { + for (StatementMatcher statementMatcher : wildcardMatchers) { + if (statementMatcher != s && statementMatcher.covers(s)) { + return false; + } + } + + return true; + }).collect(Collectors.toList()); + + } + + private boolean covers(StatementMatcher s) { + + if (subjectIsWildcard()) { + if (s.subjectName != null) { + return false; + } + } else { + if (!Objects.equals(subjectName, s.subjectName)) { + return false; + } + if (!Objects.equals(subjectValue, s.subjectValue)) { + return false; + } + } + + if (predicateIsWildcard()) { + if (s.predicateName != null) { + return false; + } + } else { + if (!Objects.equals(predicateName, s.predicateName)) { + return false; + } + if (!Objects.equals(predicateValue, s.predicateValue)) { + return false; + } + } + + if (objectIsWildcard()) { + if (s.objectName != null) { + return false; + } + } else { + if (!Objects.equals(objectName, s.objectName)) { + return false; + } + if (!Objects.equals(objectValue, s.objectValue)) { + return false; + } + } + + return true; + + } + public String getSubjectName() { return subjectName; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AbstractConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AbstractConstraintComponent.java index 45f4f859ca9..2464d58072d 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AbstractConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AbstractConstraintComponent.java @@ -3,7 +3,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import java.util.stream.Stream; +import java.util.UUID; import org.eclipse.rdf4j.model.Resource; import org.eclipse.rdf4j.sail.shacl.ConnectionsGroup; @@ -86,16 +86,14 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Scope scope } @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, + public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { throw new UnsupportedOperationException(this.getClass().getSimpleName()); } - @Override - public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - throw new UnsupportedOperationException(this.getClass().getSimpleName()); + static String randomSparqlVariable() { + return "?" + UUID.randomUUID().toString().replace("-", ""); } + } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java index 8a6245dae10..bffe9e9d1c6 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/AndConstraintComponent.java @@ -2,9 +2,7 @@ import java.util.List; import java.util.Set; -import java.util.UUID; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; @@ -23,7 +21,6 @@ import org.eclipse.rdf4j.sail.shacl.ast.Shape; import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment; import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher; -import org.eclipse.rdf4j.sail.shacl.ast.paths.Path; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNodeProvider; @@ -31,7 +28,7 @@ import org.eclipse.rdf4j.sail.shacl.ast.planNodes.Unique; import org.eclipse.rdf4j.sail.shacl.ast.targets.TargetChain; -public class AndConstraintComponent extends AbstractConstraintComponent { +public class AndConstraintComponent extends LogicalOperatorConstraintComponent { List and; public AndConstraintComponent(Resource id, RepositoryConnection connection, @@ -137,107 +134,10 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - boolean isFilterCondition = and.stream() - .map(o -> o.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::isFilterCondition) - .findFirst() - .orElse(false); - - if (scope == Scope.nodeShape) { - - if (!isFilterCondition) { - String collect = and - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .map(s -> s.replaceAll("(?m)^", "\t")) - .reduce((a, b) -> a + " \n " + b) - .orElse(""); - return SparqlFragment.bgp(collect); - - } else { - String collect = and - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) && ( ", "( ", - " )")); - return SparqlFragment.filterCondition(collect); - - } - } else if (scope == Scope.propertyShape) { - - if (!isFilterCondition) { - throw new UnsupportedOperationException(); - } else { - - Path path = getTargetChain().getPath().get(); - - String collect = and - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) && ( ", "( ", - " )")); - - String pathQuery1 = path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner); - - String query = pathQuery1 + "\n FILTER (! EXISTS {\n" + pathQuery1.replaceAll("(?m)^", "\t") - + "\n\tFILTER(!(" + collect + "))\n})"; - - String pathQuery2 = path.getTargetQueryFragment(subject, - StatementMatcher.Variable.getRandomInstance(), rdfsSubClassOfReasoner); - - query = "{\n" + - VALUES_INJECTION_POINT + "\n " + - "" + query.replaceAll("(?m)^", "\t") + " \n" + - "} UNION {\n" + - "\t " + VALUES_INJECTION_POINT + "\n" + - "\t ?" + subject.getName() + " " + randomVariable() + " " + randomVariable() + ".\n" + - "\t FILTER(NOT EXISTS {\n " + - "" + pathQuery2.replaceAll("(?m)^", "\t") - + " \n" + - "})\n" + - "}"; - - return SparqlFragment.bgp(query); - } - } else { - throw new UnsupportedOperationException("Unknown scope: " + scope); - } - - } + return buildSparqlValidNodes_rsx_targetShape_inner(subject, object, rdfsSubClassOfReasoner, scope, and, + getTargetChain(), + SparqlFragment::join, SparqlFragment::and); - private String randomVariable() { - return "?" + UUID.randomUUID().toString().replace("-", ""); } - @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - - StatementMatcher subjectPattern = new StatementMatcher( - object, - null, - null - ); - - StatementMatcher objectPattern = new StatementMatcher( - null, - null, - object - ); - - Stream statementPatternStream = and.stream() - .flatMap(c -> c.getStatementMatchers_rsx_targetShape(object, - StatementMatcher.Variable.getRandomInstance(), - rdfsSubClassOfReasoner, Scope.nodeShape)); - - return Stream.concat(statementPatternStream, Stream.of(subjectPattern, objectPattern)); - - } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ConstraintComponent.java index 0989883aed6..5111d1db225 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/ConstraintComponent.java @@ -1,7 +1,6 @@ package org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents; import java.util.Set; -import java.util.stream.Stream; import org.eclipse.rdf4j.sail.shacl.ConnectionsGroup; import org.eclipse.rdf4j.sail.shacl.RdfsSubClassOfReasoner; @@ -33,10 +32,6 @@ PlanNode generateTransactionalValidationPlan(ConnectionsGroup connectionsGroup, PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Scope scope); - Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope); - SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java index 9c5887c003b..85833c7d3d0 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/DashHasValueInConstraintComponent.java @@ -2,9 +2,9 @@ import java.util.Collections; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; @@ -148,26 +148,21 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Scope scope } @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, + public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { + List statementMatchers = Collections.emptyList(); + if (getTargetChain().getPath().isPresent()) { Path path = getTargetChain().getPath().get(); - return path.getStatementMatcher(subject, object, rdfsSubClassOfReasoner); -// return hasValueIn -// .stream() -// .flatMap(value -> path.getStatementPatterns(subject, object, rdfsSubClassOfReasoner)); + statementMatchers = hasValueIn.stream() + .flatMap(v -> path.getStatementMatcher(subject, new StatementMatcher.Variable(v), + rdfsSubClassOfReasoner)) + .collect(Collectors.toList()); } - throw new IllegalStateException("Dunno what to do here!"); - } - - @Override - public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { if (scope == Scope.propertyShape) { Path path = getTargetChain().getPath().get(); @@ -192,7 +187,7 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var Collectors.joining("} UNION {\n" + VALUES_INJECTION_POINT + "\n", "{\n" + VALUES_INJECTION_POINT + "\n", "}")); - return SparqlFragment.bgp(sparql); + return SparqlFragment.bgp(sparql, statementMatchers); } else { @@ -209,7 +204,7 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var }) .reduce((a, b) -> a + " || " + b) .orElseThrow(() -> new IllegalStateException("hasValueIn was empty")); - return SparqlFragment.filterCondition(sparql); + return SparqlFragment.filterCondition(sparql, statementMatchers); } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java index af82d1dd22f..78f54085b77 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/HasValueConstraintComponent.java @@ -2,8 +2,9 @@ import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; -import java.util.stream.Stream; +import java.util.stream.Collectors; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; @@ -134,33 +135,30 @@ public PlanNode getAllTargetsPlan(ConnectionsGroup connectionsGroup, Scope scope } @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, + public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { + List statementMatchers = Collections.emptyList(); + if (getTargetChain().getPath().isPresent()) { Path path = getTargetChain().getPath().get(); - return path.getStatementMatcher(subject, object, rdfsSubClassOfReasoner); + statementMatchers = path + .getStatementMatcher(subject, new StatementMatcher.Variable(hasValue), rdfsSubClassOfReasoner) + .collect(Collectors.toList()); } - throw new IllegalStateException("Dunno what to do here!"); - } - - @Override - public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { if (scope == Scope.propertyShape) { Path path = getTargetChain().getPath().get(); if (hasValue.isIRI()) { return SparqlFragment.bgp("BIND(<" + hasValue + "> as ?" + object.getName() + ")\n" - + path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner)); + + path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner), statementMatchers); } if (hasValue.isLiteral()) { return SparqlFragment.bgp("BIND(" + hasValue.toString() + " as ?" + object.getName() + ")\n" - + path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner)); + + path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner), statementMatchers); } throw new UnsupportedOperationException( @@ -168,9 +166,10 @@ public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Var } else { if (hasValue.isIRI()) { - return SparqlFragment.filterCondition("?" + object.getName() + " = <" + hasValue + ">"); + return SparqlFragment.filterCondition("?" + object.getName() + " = <" + hasValue + ">", + statementMatchers); } else if (hasValue.isLiteral()) { - return SparqlFragment.filterCondition("?" + object.getName() + " = " + hasValue); + return SparqlFragment.filterCondition("?" + object.getName() + " = " + hasValue, statementMatchers); } throw new UnsupportedOperationException( "value was unsupported type: " + hasValue.getClass().getSimpleName()); diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LogicalOperatorConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LogicalOperatorConstraintComponent.java new file mode 100644 index 00000000000..f1cfa68fbe8 --- /dev/null +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/LogicalOperatorConstraintComponent.java @@ -0,0 +1,124 @@ +package org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.eclipse.rdf4j.model.Resource; +import org.eclipse.rdf4j.sail.shacl.RdfsSubClassOfReasoner; +import org.eclipse.rdf4j.sail.shacl.ast.Shape; +import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment; +import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher; +import org.eclipse.rdf4j.sail.shacl.ast.paths.Path; +import org.eclipse.rdf4j.sail.shacl.ast.targets.TargetChain; + +public abstract class LogicalOperatorConstraintComponent extends AbstractConstraintComponent { + public LogicalOperatorConstraintComponent(Resource id) { + super(id); + } + + /** + * + * @param subject the subject from buildSparqlValidNodes_rsx_targetShape + * @param object the object from buildSparqlValidNodes_rsx_targetShape + * @param rdfsSubClassOfReasoner the rdfsSubClassOfReasoner from buildSparqlValidNodes_rsx_targetShape + * @param scope the scope from buildSparqlValidNodes_rsx_targetShape + * @param shapes the shapes from from the logical constraint (eg. and, or) + * @param targetChain the current targetChain + * @param bgpCombiner the SparqlFragment combiner for bgp or union fragments (eg. SparqlFragment::join + * for AND; SparqlFragment::union for OR) + * @param filterCombiner the SparqlFragment combiner for filter condition fragments (eg. SparqlFragment::and + * for AND; SparqlFragment::or for OR) + * @return the new SparqlFragment that handles sh:and or sh:or for the shapes provided + */ + static SparqlFragment buildSparqlValidNodes_rsx_targetShape_inner(StatementMatcher.Variable subject, + StatementMatcher.Variable object, + RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope, List shapes, TargetChain targetChain, + Function, SparqlFragment> bgpCombiner, + Function, SparqlFragment> filterCombiner) { + + List sparqlFragments = shapes.stream() + .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, + scope)) + .collect(Collectors.toList()); + + if (scope == Scope.nodeShape) { + + if (!SparqlFragment.isFilterCondition(sparqlFragments)) { + return bgpCombiner.apply(sparqlFragments); + } else { + return filterCombiner.apply(sparqlFragments); + } + + } else if (scope == Scope.propertyShape) { + + if (!SparqlFragment.isFilterCondition(sparqlFragments)) { + throw new UnsupportedOperationException(); + } else { + + assert targetChain.getPath().isPresent(); + + Path path = targetChain.getPath().get(); + + StatementMatcher.Variable filterNotExistsVariable = StatementMatcher.Variable.getRandomInstance(); + + SparqlFragment filterCondition = filterCombiner.apply(shapes.stream() + .map(c -> c.buildSparqlValidNodes_rsx_targetShape(subject, filterNotExistsVariable, + rdfsSubClassOfReasoner, + scope)) + .collect(Collectors.toList())); + + String pathQuery1 = path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner); + String pathQuery2 = path.getTargetQueryFragment(subject, filterNotExistsVariable, + rdfsSubClassOfReasoner); + String pathQuery3 = path.getTargetQueryFragment(subject, StatementMatcher.Variable.getRandomInstance(), + rdfsSubClassOfReasoner); + + // check that all values for the path from our subject match the filter condition + String unionCondition1 = String.join("\n", "", + pathQuery1, + "FILTER ( NOT EXISTS {", + SparqlFragment.indent(pathQuery2), + "\tFILTER(!(" + + filterCondition.getFragment() + + "))", + "})"); + + // alternately there could be no values for the path from our subject, in which case the subject would + // also be valid + String unionCondition2 = "\t ?" + subject.getName() + " " + randomSparqlVariable() + " " + + randomSparqlVariable() + + ".\n" + + "\t FILTER(NOT EXISTS {\n " + + SparqlFragment.indent(pathQuery3) + + " \n" + + "})\n"; + + // same as above, except we check for statements where our subject is actually used as an object in a + // statement + String unionCondition3 = "\t " + randomSparqlVariable() + " " + randomSparqlVariable() + " ?" + + subject.getName() + + ".\n" + + "\t FILTER(NOT EXISTS {\n " + + SparqlFragment.indent(pathQuery3) + + " \n" + + "})\n"; + + List statementMatchers = SparqlFragment.getStatementMatchers(sparqlFragments); + + statementMatchers.add(new StatementMatcher(subject, null, null)); + statementMatchers.add(new StatementMatcher(null, null, subject)); + + SparqlFragment sparqlFragment = SparqlFragment.union(unionCondition1, unionCondition2, unionCondition3); + sparqlFragment.addStatementMatchers(statementMatchers); + + return sparqlFragment; + } + } else { + throw new UnsupportedOperationException("Unknown scope: " + scope); + } + } + +} diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java index c0cdd346288..15ab7964cfa 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/constraintcomponents/OrConstraintComponent.java @@ -3,9 +3,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.UUID; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; @@ -24,7 +22,6 @@ import org.eclipse.rdf4j.sail.shacl.ast.Shape; import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment; import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher; -import org.eclipse.rdf4j.sail.shacl.ast.paths.Path; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EmptyNode; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.EqualsJoinValue; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.PlanNode; @@ -34,7 +31,7 @@ import org.eclipse.rdf4j.sail.shacl.ast.planNodes.Unique; import org.eclipse.rdf4j.sail.shacl.ast.targets.TargetChain; -public class OrConstraintComponent extends AbstractConstraintComponent { +public class OrConstraintComponent extends LogicalOperatorConstraintComponent { List or; public OrConstraintComponent(Resource id, RepositoryConnection connection, @@ -164,167 +161,14 @@ public boolean requiresEvaluation(ConnectionsGroup connectionsGroup, Scope scope return or.stream().anyMatch(c -> c.requiresEvaluation(connectionsGroup, scope)); } -// @Override -// public String buildSparqlValidNodes_rsx_targetShape(Var subject, Var object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { -// if (scope == Scope.propertyShape) { -// // within property shape -// String objectVariable = randomVariable(); -// String pathQuery1 = getTargetChain().getPath().get().getTargetQueryFragment(subject, object, null); -// -// String collect = or.stream() -// .map(l -> l.stream() -// .map(p -> p.buildSparqlValidNodes(objectVariable)) -// .reduce((a, b) -> a + " && " + b)) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.joining(" ) || ( ", "( ", -// " )")); -// -// String query = pathQuery1 + "\n FILTER (! EXISTS {\n" + pathQuery1.replaceAll("(?m)^", "\t") -// + "\n\tFILTER(!(" + collect + "))\n})"; -// -// String pathQuery2 = getPath().getQuery(targetVar, randomVariable(), null); -// -// query = "{\n" + VALUES_INJECTION_POINT + "\n " + query.replaceAll("(?m)^", "\t") -// + " \n} UNION {\n\t" + VALUES_INJECTION_POINT + "\n\t" + targetVar + " " -// + randomVariable() + " " -// + randomVariable() + ".\n\tFILTER(NOT EXISTS {\n " + pathQuery2.replaceAll("(?m)^", "\t") -// + " \n})\n}"; -// -// return query; -// } else if (!childrenHasOwnPathRecursive()) { -// -// return or.stream() -// .map(l -> l.stream() -// .map(p -> p.buildSparqlValidNodes(targetVar)) -// .reduce((a, b) -> a + " && " + b)) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .collect(Collectors.joining(" ) || ( ", "( ", -// " )")); -// } else { -// // within node shape -// return or.stream() -// .map(l -> l.stream().map(p -> p.buildSparqlValidNodes(targetVar)).reduce((a, b) -> a + "\n" + b)) -// .filter(Optional::isPresent) -// .map(Optional::get) -// .map(s -> s.replaceAll("(?m)^", "\t")) -// .collect( -// Collectors.joining("\n} UNION {\n" + VALUES_INJECTION_POINT + "\n", -// "{\n" + VALUES_INJECTION_POINT + "\n", -// "\n}")); -// } -// } - @Override public SparqlFragment buildSparqlValidNodes_rsx_targetShape(StatementMatcher.Variable subject, StatementMatcher.Variable object, RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - boolean isFilterCondition = or.stream() - .map(o -> o.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::isFilterCondition) - .findFirst() - .orElse(false); - - if (scope == Scope.nodeShape) { - - if (!isFilterCondition) { - String collect = or - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .map(s -> s.replaceAll("(?m)^", "\t")) - .collect( - Collectors.joining( - "\n} UNION {\n" + VALUES_INJECTION_POINT + "\n", - "{\n" + VALUES_INJECTION_POINT + "\n", - "\n}")); - return SparqlFragment.bgp(collect); - - } else { - String collect = or - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) || ( ", "( ", " )")); - return SparqlFragment.filterCondition(collect); - - } - } else if (scope == Scope.propertyShape) { - - if (!isFilterCondition) { - throw new UnsupportedOperationException(); - } else { - - Path path = getTargetChain().getPath().get(); - - String collect = or - .stream() - .map(shape -> shape.buildSparqlValidNodes_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, scope)) - .map(SparqlFragment::getFragment) - .collect(Collectors.joining(" ) || ( ", "( ", - " )")); - - String pathQuery1 = path.getTargetQueryFragment(subject, object, rdfsSubClassOfReasoner); - - String query = pathQuery1 + "\n FILTER (! EXISTS {\n" + pathQuery1.replaceAll("(?m)^", "\t") - + "\n\tFILTER(!(" + collect + "))\n})"; - - String pathQuery2 = path.getTargetQueryFragment(subject, - new StatementMatcher.Variable(UUID.randomUUID().toString().replace("-", "")), - rdfsSubClassOfReasoner); - - query = "{\n" + - VALUES_INJECTION_POINT + "\n " + - "" + query.replaceAll("(?m)^", "\t") + " \n" + - "} UNION {\n" + - "\t " + VALUES_INJECTION_POINT + "\n" + - "\t ?" + subject.getName() + " " + randomVariable() + " " + randomVariable() + ".\n" + - "\t FILTER(NOT EXISTS {\n " + - "" + pathQuery2.replaceAll("(?m)^", "\t") - + " \n" + - "})\n" + - "}"; - - return SparqlFragment.bgp(query); - } - } else { - throw new UnsupportedOperationException("Unknown scope: " + scope); - } - - } - - private String randomVariable() { - return "?" + UUID.randomUUID().toString().replace("-", ""); - } - - @Override - public Stream getStatementMatchers_rsx_targetShape(StatementMatcher.Variable subject, - StatementMatcher.Variable object, - RdfsSubClassOfReasoner rdfsSubClassOfReasoner, Scope scope) { - - StatementMatcher subjectPattern = new StatementMatcher( - object, - null, - null - ); - - StatementMatcher objectPattern = new StatementMatcher( - null, - null, - object - ); - - Stream statementPatternStream = or.stream() - .flatMap(c -> c.getStatementMatchers_rsx_targetShape(object, - new StatementMatcher.Variable("someVarName"), - rdfsSubClassOfReasoner, Scope.nodeShape)); - - return Stream.concat(statementPatternStream, Stream.of(subjectPattern, objectPattern)); + return buildSparqlValidNodes_rsx_targetShape_inner(subject, object, rdfsSubClassOfReasoner, scope, or, + getTargetChain(), + SparqlFragment::union, SparqlFragment::or); } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java index a99bf4e9512..5c44aee5a0e 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/AbstractBulkJoinPlanNode.java @@ -27,6 +27,7 @@ import org.eclipse.rdf4j.query.parser.QueryParserRegistry; import org.eclipse.rdf4j.sail.SailConnection; import org.eclipse.rdf4j.sail.shacl.GlobalValidationExecutionLogging; +import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.AbstractConstraintComponent; public abstract class AbstractBulkJoinPlanNode implements PlanNode { @@ -38,7 +39,7 @@ ParsedQuery parseQuery(String query) { // #VALUES_INJECTION_POINT# is an annotation in the query where there is a "new scope" due to the bottom up // semantics of SPARQL but where we don't actually want a new scope. - query = query.replace("#VALUES_INJECTION_POINT#", "\nVALUES (?a) {}\n"); + query = query.replace(AbstractConstraintComponent.VALUES_INJECTION_POINT, "\nVALUES (?a) {}\n"); String completeQuery = "select * where { \nVALUES (?a) {}\n" + query + "\n}\nORDER BY ?a"; return queryParserFactory.getParser().parseQuery(completeQuery, null); } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java index 6a455ab2ddc..2c5e4e44360 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/planNodes/BindSelect.java @@ -34,6 +34,7 @@ import org.eclipse.rdf4j.sail.SailException; import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection; import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher; +import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.AbstractConstraintComponent; import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent; import org.eclipse.rdf4j.sail.shacl.ast.targets.EffectiveTarget; import org.slf4j.Logger; @@ -263,8 +264,8 @@ private ParsedQuery getParsedQuery(int targetChainSize) { String query = BindSelect.this.query; - query = query.replace("#VALUES_INJECTION_POINT#", values.toString()); - query = "select * where { " + values.toString() + query + "\n}"; + query = query.replace(AbstractConstraintComponent.VALUES_INJECTION_POINT, values.toString()); + query = "select * where { " + values + query + "\n}"; QueryParserFactory queryParserFactory = QueryParserRegistry.getInstance() .get(QueryLanguage.SPARQL) diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java index a2e0a4e0455..779e6ffa887 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/EffectiveTarget.java @@ -178,12 +178,21 @@ public PlanNode getPlanNode(ConnectionsGroup connectionsGroup, ConstraintCompone .reduce((a, b) -> a + "\n" + b) .orElse(""); + List statementMatchersRemoval = optional != null + ? optional.getStatementMatcher().collect(Collectors.toCollection(ArrayList::new)) + : new ArrayList<>(); + + if (chain.getFirst().target instanceof RSXTargetShape) { + statementMatchersRemoval.addAll(chain.getFirst().getStatementMatcher().collect(Collectors.toList())); + includeTargetsAffectedByRemoval = true; + } + TargetChainRetriever targetChainRetriever; - if (includeTargetsAffectedByRemoval && optional != null) { + if (includeTargetsAffectedByRemoval) { targetChainRetriever = new TargetChainRetriever( connectionsGroup, statementMatchers, - optional.getStatementMatcher().collect(Collectors.toList()), + statementMatchersRemoval, query, getVars(), scope diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java index 19416660353..e567c37fb33 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/RSXTargetShape.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.rdf4j.model.IRI; @@ -22,6 +21,7 @@ import org.eclipse.rdf4j.sail.shacl.ast.PropertyShape; import org.eclipse.rdf4j.sail.shacl.ast.ShaclProperties; import org.eclipse.rdf4j.sail.shacl.ast.Shape; +import org.eclipse.rdf4j.sail.shacl.ast.SparqlFragment; import org.eclipse.rdf4j.sail.shacl.ast.StatementMatcher; import org.eclipse.rdf4j.sail.shacl.ast.constraintcomponents.ConstraintComponent; import org.eclipse.rdf4j.sail.shacl.ast.planNodes.ExternalFilterByQuery; @@ -68,18 +68,21 @@ public PlanNode getAdded(ConnectionsGroup connectionsGroup, ConstraintComponent. private PlanNode getAddedRemovedInner(ConnectionsGroup connectionsGroup, ConstraintComponent.Scope scope, SailConnection connection) { - List collect = getStatementMatcher(null, new StatementMatcher.Variable("temp1"), - connectionsGroup.getRdfsSubClassOfReasoner()).collect(Collectors.toList()); + StatementMatcher.Variable object = new StatementMatcher.Variable("temp1"); - String query = getTargetQueryFragment(null, new StatementMatcher.Variable("temp1"), - connectionsGroup.getRdfsSubClassOfReasoner()); + SparqlFragment sparqlFragment = this.targetShape.buildSparqlValidNodes_rsx_targetShape(null, object, + connectionsGroup.getRdfsSubClassOfReasoner(), null); + + List statementMatchers = sparqlFragment.getStatementMatchers(); - List vars = Collections.singletonList(new StatementMatcher.Variable("temp1")); + String query = sparqlFragment.getFragment(); + + List vars = Collections.singletonList(object); return new Unique(new TargetChainRetriever( connectionsGroup, - collect, - null, + statementMatchers, + statementMatchers, query, vars, scope @@ -113,8 +116,9 @@ public Stream getStatementMatcher(StatementMatcher.Variable su RdfsSubClassOfReasoner rdfsSubClassOfReasoner) { assert (subject == null); - return this.targetShape.getStatementMatchers_rsx_targetShape(subject, object, - rdfsSubClassOfReasoner, null); + return this.targetShape.buildSparqlValidNodes_rsx_targetShape(subject, object, rdfsSubClassOfReasoner, null) + .getStatementMatchers() + .stream(); } @Override diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java index df8b72353db..f6e329c3bed 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/targets/TargetChainRetriever.java @@ -38,7 +38,7 @@ public class TargetChainRetriever implements PlanNode { private static final Logger logger = LoggerFactory.getLogger(TargetChainRetriever.class); private final ConnectionsGroup connectionsGroup; - private final List statementPatterns; + private final List statementMatchers; private final List removedStatementMatchers; private final String query; private final QueryParserFactory queryParserFactory; @@ -47,10 +47,11 @@ public class TargetChainRetriever implements PlanNode { private ValidationExecutionLogger validationExecutionLogger; public TargetChainRetriever(ConnectionsGroup connectionsGroup, - List statementPatterns, List removedStatementMatchers, String query, + List statementMatchers, List removedStatementMatchers, String query, List vars, ConstraintComponent.Scope scope) { this.connectionsGroup = connectionsGroup; - this.statementPatterns = statementPatterns; + this.statementMatchers = StatementMatcher.reduce(statementMatchers); + this.scope = scope; String sparqlProjection = vars.stream() @@ -58,16 +59,17 @@ public TargetChainRetriever(ConnectionsGroup connectionsGroup, .reduce((a, b) -> a + " " + b) .orElseThrow(IllegalStateException::new); - this.query = "select " + sparqlProjection + " where {" + query + "}"; + this.query = "select " + sparqlProjection + " where {\n" + query + "\n}"; // this.stackTrace = Thread.currentThread().getStackTrace(); queryParserFactory = QueryParserRegistry.getInstance() .get(QueryLanguage.SPARQL) .get(); - this.removedStatementMatchers = removedStatementMatchers != null ? removedStatementMatchers + this.removedStatementMatchers = removedStatementMatchers != null + ? StatementMatcher.reduce(removedStatementMatchers) : Collections.emptyList(); - assert this.removedStatementMatchers.size() <= 1; + } @Override @@ -75,7 +77,7 @@ public CloseableIteration iterator() { return new LoggingCloseableIteration(this, validationExecutionLogger) { - final Iterator statementPatternIterator = statementPatterns.iterator(); + final Iterator statementPatternIterator = statementMatchers.iterator(); final Iterator removedStatementIterator = removedStatementMatchers.iterator(); StatementMatcher currentStatementMatcher; @@ -86,6 +88,9 @@ public CloseableIteration iterator() { ParsedQuery parsedQuery; + // for de-duping bindings + MapBindingSet previousBindings; + public void calculateNextStatementMatcher() { if (statements != null && statements.hasNext()) { return; @@ -116,6 +121,8 @@ public void calculateNextStatementMatcher() { currentStatementMatcher = statementPatternIterator.next(); connection = connectionsGroup.getAddedStatements(); } else { + if (!connectionsGroup.getStats().hasRemoved()) + break; currentStatementMatcher = removedStatementIterator.next(); connection = connectionsGroup.getRemovedStatements(); } @@ -126,6 +133,8 @@ public void calculateNextStatementMatcher() { currentStatementMatcher.getObjectValue(), false); } while (!statements.hasNext()); + previousBindings = null; + } private void calculateNextResult() { @@ -143,9 +152,9 @@ private void calculateNextResult() { MapBindingSet bindings = new MapBindingSet(); - if (statements == null || !statements.hasNext()) { + while (statements == null || !statements.hasNext()) { calculateNextStatementMatcher(); - if (statements == null || !statements.hasNext()) { + if (statements == null) { return; } } @@ -171,6 +180,12 @@ private void calculateNextResult() { bindings.addBinding(currentStatementMatcher.getObjectName(), next.getObject()); } + if (bindingsEquivalent(currentStatementMatcher, bindings, previousBindings)) { + continue; + } + + previousBindings = bindings; + // TODO: Should really bulk this operation! results = connectionsGroup.getBaseConnection() @@ -233,6 +248,36 @@ protected boolean localHasNext() throws SailException { }; } + private static boolean bindingsEquivalent(StatementMatcher currentStatementMatcher, MapBindingSet bindings, + MapBindingSet previousBindings) { + if (currentStatementMatcher == null || bindings == null || previousBindings == null) { + return false; + } + + boolean equivalent = true; + + if (equivalent && currentStatementMatcher.getSubjectValue() == null + && !currentStatementMatcher.subjectIsWildcard()) { + equivalent = Objects.equals(bindings.getBinding(currentStatementMatcher.getSubjectName()), + previousBindings.getBinding(currentStatementMatcher.getSubjectName())); + } + + if (equivalent && currentStatementMatcher.getPredicateValue() == null + && !currentStatementMatcher.predicateIsWildcard()) { + equivalent = Objects.equals(bindings.getBinding(currentStatementMatcher.getPredicateName()), + previousBindings.getBinding(currentStatementMatcher.getPredicateName())); + } + + if (equivalent && currentStatementMatcher.getObjectValue() == null + && !currentStatementMatcher.objectIsWildcard()) { + equivalent = Objects.equals(bindings.getBinding(currentStatementMatcher.getObjectName()), + previousBindings.getBinding(currentStatementMatcher.getObjectName())); + } + + return equivalent; + + } + @Override public int depth() { return 0; @@ -272,7 +317,7 @@ public boolean equals(Object o) { return false; } TargetChainRetriever that = (TargetChainRetriever) o; - return statementPatterns.equals(that.statementPatterns) && + return statementMatchers.equals(that.statementMatchers) && removedStatementMatchers.equals(that.removedStatementMatchers) && query.equals(that.query) && scope == that.scope; @@ -280,13 +325,13 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(statementPatterns, removedStatementMatchers, query, scope); + return Objects.hash(statementMatchers, removedStatementMatchers, query, scope); } @Override public String toString() { return "TargetChainRetriever{" + - "statementPatterns=" + statementPatterns + + "statementPatterns=" + statementMatchers + ", removedStatementMatchers=" + removedStatementMatchers + ", query='" + query.replace("\n", "\t") + '\'' + ", scope=" + scope + diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java index be5e6bb3dab..7cbb31960ff 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java @@ -224,8 +224,10 @@ abstract public class AbstractShaclTest { "test-cases/hasValue/targetShapeOr", "test-cases/hasValue/targetShapeAnd", "test-cases/hasValue/targetShapeAnd2", + "test-cases/hasValue/targetShapeAnd3", "test-cases/hasValue/targetShapeAndOr", "test-cases/hasValue/targetShapeAndOr2", + "test-cases/hasValue/targetShapeAndOr3", "test-cases/hasValueIn/targetShapeOr", "test-cases/hasValueIn/or", "test-cases/class/simpleNested", diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/TargetShapeBenchmark.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/TargetShapeBenchmark.java new file mode 100644 index 00000000000..ee383b9844c --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/TargetShapeBenchmark.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2021 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ + +package org.eclipse.rdf4j.sail.shacl.benchmark; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.rdf4j.IsolationLevels; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.sail.shacl.GlobalValidationExecutionLogging; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; +import org.eclipse.rdf4j.sail.shacl.ShaclSailConnection; +import org.eclipse.rdf4j.sail.shacl.Utils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Logger; + +/** + * @author HÃ¥vard Ottestad + */ +@State(Scope.Benchmark) +@Warmup(iterations = 20) +@BenchmarkMode({ Mode.AverageTime }) +@Fork(value = 1, jvmArgs = { "-Xmx1G", "-XX:+UseSerialGC" }) +//@Fork(value = 1, jvmArgs = {"-Xms8G", "-Xmx8G", "-XX:+UseSerialGC", "-XX:+UnlockCommercialFeatures", "-XX:StartFlightRecording=delay=5s,duration=120s,filename=recording.jfr,settings=profile", "-XX:FlightRecorderOptions=samplethreads=true,stackdepth=1024", "-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints"}) +@Measurement(iterations = 10) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class TargetShapeBenchmark { + { + GlobalValidationExecutionLogging.loggingEnabled = false; + } + + @Setup(Level.Trial) + public void setUp() throws InterruptedException { + Logger root = (Logger) LoggerFactory.getLogger(ShaclSailConnection.class.getName()); + root.setLevel(ch.qos.logback.classic.Level.INFO); + } + + @Benchmark + public void shacl() throws Exception { + + SailRepository repository = new SailRepository( + Utils.getInitializedShaclSail("benchmark/targetShape/shapes.ttl")); + + ((ShaclSail) repository.getSail()).setDashDataShapes(true); + ((ShaclSail) repository.getSail()).setEclipseRdf4jShaclExtensions(true); + + try (SailRepositoryConnection connection = repository.getConnection()) { + + connection.begin(IsolationLevels.SNAPSHOT); + connection.add(TargetShapeBenchmark.class.getClassLoader().getResource("benchmark/targetShape/data.ttl"), + RDFFormat.TURTLE); + connection.commit(); + } + + repository.shutDown(); + } + +} diff --git a/core/sail/shacl/src/test/resources/benchmark/targetShape/data.ttl b/core/sail/shacl/src/test/resources/benchmark/targetShape/data.ttl new file mode 100644 index 00000000000..c7d7aa0cf71 --- /dev/null +++ b/core/sail/shacl/src/test/resources/benchmark/targetShape/data.ttl @@ -0,0 +1,140 @@ +@base . +@prefix voc: . +@prefix so: . + + a voc:Droid, voc:Character; + voc:name "R2-D2"; + voc:primaryFunction "Repair droid"; + voc:descr "Smart and funny (also giggles)"; + voc:friends , . + + a voc:Human, voc:AllHuman, voc:Character; + voc:name "Luke Skywalker"; + voc:descr "intern Jeddai"; + voc:height 1.72; + voc:mass 59.0; + voc:numberSlavesPossessed 1; + voc:friends , . + + a voc:Human, voc:AllHuman, voc:Character; + voc:name "Leia Organa"; + voc:descr "Fabulous princess"; + voc:height 1.68; + voc:age 32; + voc:numberSlavesPossessed 0; + # voc:mass: You don't ask a woman about that + voc:friends , . + + a voc:Human, voc:AllHuman, voc:Character; + voc:name "Darth Vader"; + voc:descr "evil overlord"; + voc:height 2.10; + voc:mass 140.0 ; + voc:numberSlavesPossessed 1000. + # voc:friend: None + + a voc:Droid, voc:Character; + voc:name "C-3PO"; + voc:primaryFunction "Translator droid"; + #voc:descr None + voc:friend . + + a voc:Droid, voc:DroidAlternative, voc:Character; + voc:name "Alty"; + voc:descr "Droid with multiple self types". + + a voc:DroidAlternative, voc:Character; + voc:name "Alty Single"; + voc:descr "Droid with only the alternative type". + + a voc:Droid, voc:Character; + voc:name "ABC-123"; + voc:descr "droid 123"; + voc:bestfriend ; + voc:friends . + + a voc:DroidWithMandatoryInfo, voc:Character; + voc:name "MI-123"; + voc:descr "droid MI 123 missing mandatory info". + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:name "Slaves have no name"; + voc:descr "very important"; + voc:height 1.95; + voc:mass 79.0; + voc:age 33; + voc:clonedOn "2018-01-01"^^xsd:date; + voc:imprisonedOn "2018-01-02"^^xsd:date; + voc:enemies , ; + voc:bestfriend ; + voc:friends , ; + voc:mandatoryfriends , ; + voc:friendsNoRangeCheck ; + voc:anyHumanFriends , , ; + voc:info "This is slave1, it inherits from AllHuman, Clone, and Character". + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:name "Slaves have no name2"; + voc:descr "one that misses mandatory field mandatoryfriends" ; + voc:age 22; + voc:imprisonedOn "2018-01-01"^^xsd:date; + voc:bestfriend . + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:imprisonedOn "2019-01-02"^^xsd:date; + voc:name "Slaves 3"; + voc:friends . + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:imprisonedOn "2010-01-02"^^xsd:date; + voc:name "Slaves 4"; + voc:bestfriend . + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:name "Slave With Inverse Friends"; + voc:imprisonedOn "2005-01-02"^^xsd:date; + voc:descr "has inverse friends inversed from friends property". + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character, voc:SomethingExtra; + voc:name "Slave With Inverse Friends"; + voc:descr "has inverse friends inversed from friends property". + + a voc:CloneSoldier, voc:Clone, voc:AllHuman, voc:Character; + voc:name "CloneSoldier With Inverse Friends inversed from bestfriend". + + a voc:CloneSlave; + voc:name "CloneSlave who has inverse friendzonedinv from a CloneFriend". + + a voc:CloneFriend, voc:Clone, voc:AllHuman, voc:Character; + voc:name "CloneFriend who friendzoned a cloneslave"; + voc:friendZoned . + + a voc:CloneAlly; + voc:name "CloneAlly1, who should have bestFriendInv CloneAlly2". + + a voc:CloneAlly; + voc:name "CloneAlly2, who has CloneAlly1 as bestfriend"; + voc:enemy . + +### +#data for testing INHERITING NAME with rdfProp +### + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:name "Slave SlaveWithScooter1"; + voc:scooter . + + a voc:Scooter, voc:Vehicle; + voc:name "This should NEVER be seen, as name property is overridden in the parent Vehicle class"; + voc:nameInRdf "We should display this name". + + a voc:Slave, voc:Clone, voc:AllHuman, voc:Character; + voc:name "Slave SlaveWithScooter2"; + voc:scooter . + + a voc:Scooter, voc:Vehicle; + voc:name "This should NEVER be seen, as name property is overridden in the parent Vehicle class". + +### +# END of data for testing INHERITING NAME with rdfProp +### + diff --git a/core/sail/shacl/src/test/resources/benchmark/targetShape/shapes.ttl b/core/sail/shacl/src/test/resources/benchmark/targetShape/shapes.ttl new file mode 100644 index 00000000000..1503241f7c0 --- /dev/null +++ b/core/sail/shacl/src/test/resources/benchmark/targetShape/shapes.ttl @@ -0,0 +1,484 @@ +@prefix : . +@prefix voc: . +@prefix vocsh: . +@prefix so: . +@prefix affected: . +@prefix res: . +@prefix dct: . +@prefix gn: . +@prefix owl: . +@prefix puml: . +@prefix rdf: . +@prefix rdfs: . +@prefix skos: . +@prefix void: . +@prefix wgs84: . +@prefix xsd: . +@prefix sh: . +@prefix dash: . +@prefix rsx: . +@prefix ec: . +@prefix ecinst: . +@prefix voc: . +@prefix vocsh: . + +vocsh:_Character + a sh:NodeShape ; + rsx:targetShape [ a sh:NodeShape ; sh:and( [sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ;] ) ; ]; +; + sh:property [ + sh:path voc:name ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:descr ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:maxCount 1 ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:info ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:info3 ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:info4 ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] . + +vocsh:Droid + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ; ] ]; +; + sh:property [ + sh:path voc:primaryFunction ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] . + +vocsh:_AllHuman + a sh:NodeShape ; + rsx:targetShape [ a sh:NodeShape ; sh:and( [sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ;] ) ; ]; +; + sh:property [ + sh:path voc:height ; + sh:maxCount 1 ; + sh:datatype xsd:decimal ; + ] ; + sh:property [ + sh:path voc:mass ; + sh:maxCount 1 ; + sh:datatype xsd:decimal ; + ] ; + sh:property [ + sh:path voc:age ; + sh:maxCount 1 ; + sh:datatype xsd:integer ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] . + +vocsh:Human + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ]; +; + sh:property [ + sh:path voc:info ; + sh:maxCount 5 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:numberSlavesPossessed ; + sh:maxCount 1 ; + sh:datatype xsd:integer ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] . + +vocsh:_Clone + a sh:NodeShape ; + rsx:targetShape [ a sh:NodeShape ; sh:and( [sh:or( [sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ;] ) ; ]; +; + sh:property [ + sh:path voc:clonedOn ; + sh:maxCount 1 ; + sh:datatype xsd:date ; + ] ; + sh:property [ + sh:path voc:info4 ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:scooter ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] . + +vocsh:Slave + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:Slave ; ] ]; +; + sh:property [ + sh:path voc:imprisonedOn ; + sh:maxCount 1 ; + sh:datatype xsd:date ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:maxCount 10 ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriendInv ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Slave ; ] ) ; + ] ; + sh:property [ + sh:path voc:info ; + sh:maxCount 6 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:info3 ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:scooter ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ; + ] . + +vocsh:CloneSoldier + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ] ]; +; + sh:property [ + sh:path voc:bestfriendInv ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:scooter ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ; + ] . + +vocsh:CloneSlave + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ] ]; +; + sh:property [ + sh:path voc:friendZonedSlaveInv ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:scooter ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ; + ] . + +vocsh:CloneFriend + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ]; +; + sh:property [ + sh:path voc:friendZoned ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ] ) ; + ] ; + sh:property [ + sh:path voc:friends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemies ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:bestfriend ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:mandatoryfriends ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Human ; ] ) ; + ] ; + sh:property [ + sh:path voc:friendsNoRangeCheck ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:anyHumanFriends ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:acquaintance ; + sh:node ( sh:and[ sh:or( [sh:path rdf:type ; sh:or( [sh:hasValue voc:Droid ; ][sh:hasValue voc:DroidAlternative ; ] ) ;][sh:path rdf:type ; sh:hasValue voc:AllHuman ; ][sh:path rdf:type ; sh:hasValue voc:Human ; ][sh:path rdf:type ; sh:hasValue voc:Clone ; ][sh:path rdf:type ; sh:hasValue voc:Slave ; ][sh:path rdf:type ; sh:hasValue voc:CloneSoldier ; ][sh:path rdf:type ; sh:hasValue voc:CloneSlave ; ][sh:path rdf:type ; sh:hasValue voc:CloneFriend ; ] ) ; ] ) ; + ] ; + sh:property [ + sh:path voc:scooter ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ; + ] . + +vocsh:CloneAlly + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneAlly ; ] ]; +; + sh:property [ + sh:path voc:enemy ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneAlly ; ] ) ; + ] ; + sh:property [ + sh:path voc:enemyInv ; + sh:maxCount 1 ; + sh:node ( sh:property[ sh:path rdf:type ; sh:hasValue voc:CloneAlly ; ] ) ; + ] . + +vocsh:Movie + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:Movie ; ] ]; +; + sh:property [ + sh:path voc:title ; + sh:maxCount 1 ; + sh:datatype xsd:string ; + ] ; + sh:property [ + sh:path voc:globalinfo ; + sh:minCount 1 ; + sh:maxCount 1 ; + sh:datatype xsd:integer ; + ] . + +vocsh:_Vehicle + a sh:NodeShape ; + rsx:targetShape [ a sh:NodeShape ; sh:and( [sh:or( [sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ) ;] ) ; ]; +. + +vocsh:Scooter + a sh:NodeShape ; + rsx:targetShape [ a sh:Shape ; sh:property[ sh:path rdf:type ; sh:hasValue voc:Scooter ; ] ]; +. + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case1/report.ttl index 3bcec559b1a..ea45f860799 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case1/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case1/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sf97x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sf97x5 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sf97x5 ] . + +_:node1f3n3sf97x5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case2/report.ttl index 3bcec559b1a..379145e3016 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case2/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case2/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; - sh:focusNode ex:validPerson1; + sh:focusNode "blue"; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfd5x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfd5x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfd5x5 ] . + +_:node1f3n3sfd5x5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case3/report.ttl index 3bcec559b1a..08e99b03cae 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case3/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case3/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfh1x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfh1x5 ] . + +_:node1f3n3sfh1x5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case4/report.ttl index 37b76113076..9ade01d4ae0 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case4/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case4/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; - sh:focusNode ex:a; + sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfkex5 + ], [ a sh:ValidationResult; + sh:focusNode ex:a; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3sfkex5 ] . + +_:node1f3n3sfkex5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.ttl similarity index 85% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.ttl index deb5dc37855..9b923490010 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/initialData.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/initialData.ttl @@ -7,4 +7,3 @@ @prefix xsd: . @prefix rsx: . - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/report.ttl new file mode 100644 index 00000000000..d7d8612c1bb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case5/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbn5x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbn5x5 + ] . + +_:node1f3n4rbn5x5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.ttl similarity index 85% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.ttl index deb5dc37855..9b923490010 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/initialData.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/initialData.ttl @@ -7,4 +7,3 @@ @prefix xsd: . @prefix rsx: . - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/report.ttl new file mode 100644 index 00000000000..d0ba8b76eb5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case6/report.ttl @@ -0,0 +1,34 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbpbx5 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbpbx5 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbpbx5 + ] . + +_:node1f3n4rbpbx5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.ttl similarity index 85% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.ttl index deb5dc37855..9b923490010 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/initialData.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/initialData.ttl @@ -7,4 +7,3 @@ @prefix xsd: . @prefix rsx: . - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/report.ttl new file mode 100644 index 00000000000..21dd1469bd4 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/invalid/case7/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode "purple"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbr1x5 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbr1x5 + ] . + +_:node1f3n4rbr1x5 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case1/report.ttl index 3bcec559b1a..ed1be139be4 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case1/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case1/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbsix7 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbsix7 ] . + +_:node1f3n4rbsix7 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.ttl similarity index 85% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.ttl index deb5dc37855..9b923490010 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/initialData.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/initialData.ttl @@ -7,4 +7,3 @@ @prefix xsd: . @prefix rsx: . - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/report.ttl new file mode 100644 index 00000000000..068cc577357 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case2/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbu6x7 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rbu6x7 + ] . + +_:node1f3n4rbu6x7 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/report.ttl new file mode 100644 index 00000000000..e7e43834df3 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/invalid/case3/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rc0bx7 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n4rc0bx7 + ] . + +_:node1f3n4rc0bx7 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case1/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case1/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case1/report.ttl new file mode 100644 index 00000000000..3bcec559b1a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case1/report.ttl @@ -0,0 +1,20 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . + +[] a sh:ValidationReport; + sh:conforms false; + false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:resultSeverity sh:Violation; + sh:sourceShape [ a sh:PropertyShape; + sh:path ex:info2; + sh:minCount 1 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query1.rq new file mode 100644 index 00000000000..ee8ac928116 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query1.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + ex:validPerson1 a ex:Person . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query2.rq new file mode 100644 index 00000000000..094c0cd3cd1 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/query2.rq @@ -0,0 +1,12 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 ex:info "blue" . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/report.ttl new file mode 100644 index 00000000000..3bcec559b1a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case2/report.ttl @@ -0,0 +1,20 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . + +[] a sh:ValidationReport; + sh:conforms false; + false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:resultSeverity sh:Violation; + sh:sourceShape [ a sh:PropertyShape; + sh:path ex:info2; + sh:minCount 1 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/initialData.ttl new file mode 100644 index 00000000000..54ddd788c91 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:validPerson1 ex:info "blue", "red" . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq new file mode 100644 index 00000000000..6788d7401bb --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/query1.rq @@ -0,0 +1,10 @@ +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + ex:validPerson1 ex:info "red" . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/report.ttl new file mode 100644 index 00000000000..3bcec559b1a --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/invalid/case3/report.ttl @@ -0,0 +1,20 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . + +[] a sh:ValidationReport; + sh:conforms false; + false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:resultSeverity sh:Violation; + sh:sourceShape [ a sh:PropertyShape; + sh:path ex:info2; + sh:minCount 1 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/shacl.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/shacl.ttl new file mode 100644 index 00000000000..61925b28d10 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/shacl.ttl @@ -0,0 +1,25 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:shape1 + a sh:NodeShape ; + rsx:targetShape [ + sh:property [ + sh:path ex:info ; + sh:hasValue "blue" ; # we have to have at least have "blue" as a value for ex:info + sh:and ( [ sh:hasValue "blue" ; ] ) ; # all values for ex:info have to be "blue" + ] + ]; + + sh:property [ + sh:path ex:info2 ; + sh:minCount 1; + ] + + . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/initialData.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/report.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case1/report.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case1/report.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/initialData.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/report.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case2/report.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case2/report.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/initialData.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/initialData.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/report.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd/valid/case3/report.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case3/report.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case4/query1.rq new file mode 100644 index 00000000000..d7ed5b70136 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case4/query1.rq @@ -0,0 +1,12 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 ex:info "blue", "red" . +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case4/report.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case1/report.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd3/valid/case4/report.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case1/report.ttl index 3bcec559b1a..4e9b86bf989 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case1/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case1/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3shm3x11 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n3shm3x11 ] . + +_:node1f3n3shm3x11 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/query1.rq new file mode 100644 index 00000000000..2fa5c1c893c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/query1.rq @@ -0,0 +1,14 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 a ex:Person ; + ex:info "blue" . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/report.ttl new file mode 100644 index 00000000000..b20e5e13e62 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case2/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n6fqr9x11 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n6fqr9x11 + ] . + +_:node1f3n6fqr9x11 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/report.ttl new file mode 100644 index 00000000000..3c6bc918c61 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/invalid/case3/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n6fqsvx11 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n6fqsvx11 + ] . + +_:node1f3n6fqsvx11 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/shacl.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/shacl.ttl index a7a56062794..c91317a23ea 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/shacl.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/shacl.ttl @@ -13,8 +13,7 @@ ex:shape1 sh:property [ sh:path ex:info ; sh:and ( - [sh:or ([sh:hasValue "blue"] - [sh:hasValue "fjwklejf"])] + [sh:or ( [sh:hasValue "blue"] [sh:hasValue "fjwklejf"] ) ] [ sh:hasValue "red"] ) ; ] diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case1/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/report.ttl deleted file mode 100644 index 246488436f8..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr/valid/case2/report.ttl +++ /dev/null @@ -1,6 +0,0 @@ -@prefix ex: . -@prefix foaf: . -@prefix xsd: . -@prefix sh: . -@prefix rdf: . -@prefix rdfs: . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/query1.rq new file mode 100644 index 00000000000..9b1d5b30f39 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/query1.rq @@ -0,0 +1,15 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 ex:info ex:c . +ex:validPerson1 ex:info2 ex:c . + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/report.ttl new file mode 100644 index 00000000000..755022ee9d5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case1/report.ttl @@ -0,0 +1,21 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:c; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.ttl new file mode 100644 index 00000000000..a6f4b897931 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:c ex:info ex:c . +ex:c ex:info2 ex:c . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/query1.rq new file mode 100644 index 00000000000..ddd581179b9 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/query1.rq @@ -0,0 +1,13 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 ex:info ex:c . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/report.ttl new file mode 100644 index 00000000000..d62fa9c3e7d --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case2/report.ttl @@ -0,0 +1,21 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.ttl new file mode 100644 index 00000000000..507f15cd77c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/initialData.ttl @@ -0,0 +1,14 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:validPerson1 ex:info ex:c . +ex:validPerson1 ex:info2 ex:c . + +ex:c ex:info ex:c . +ex:c ex:info2 ex:c . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/query1.rq new file mode 100644 index 00000000000..13fb306b480 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/query1.rq @@ -0,0 +1,14 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + +ex:c ex:info ex:c . +ex:c ex:info2 ex:c . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/report.ttl new file mode 100644 index 00000000000..755022ee9d5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case3/report.ttl @@ -0,0 +1,21 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:c; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.ttl new file mode 100644 index 00000000000..507f15cd77c --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/initialData.ttl @@ -0,0 +1,14 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:validPerson1 ex:info ex:c . +ex:validPerson1 ex:info2 ex:c . + +ex:c ex:info ex:c . +ex:c ex:info2 ex:c . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/query1.rq new file mode 100644 index 00000000000..0810990c8ff --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/query1.rq @@ -0,0 +1,13 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +DELETE DATA { + +ex:c ex:info2 ex:c . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/report.ttl new file mode 100644 index 00000000000..755022ee9d5 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/invalid/case4/report.ttl @@ -0,0 +1,21 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:c; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape [ a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 + ] + ] . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/shacl.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/shacl.ttl new file mode 100644 index 00000000000..7d3b7c0e322 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/shacl.ttl @@ -0,0 +1,27 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + +ex:shape1 + a sh:NodeShape ; + rsx:targetShape [ + sh:property [ + sh:path ex:info ; + sh:or ( + [sh:and ([sh:hasValue ex:a] [sh:hasValue ex:b] ) ] + [ sh:hasValue ex:c] + ) ; + ] + ]; + + sh:property [ + sh:path ex:info2 ; + sh:minCount 1; + ] + + . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/valid/case1/query1.rq new file mode 100644 index 00000000000..2ca85d8e3bc --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/valid/case1/query1.rq @@ -0,0 +1,18 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 ex:info ex:c . +ex:validPerson1 ex:info2 ex:c . + +ex:c ex:info ex:c . +ex:c ex:info2 ex:c . + + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/valid/case1/report.ttl similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAnd2/valid/case2/report.ttl rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeAndOr3/valid/case1/report.ttl diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case1/report.ttl index 3bcec559b1a..8f83e3d2ae2 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case1/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case1/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70orlx9 + ], [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70orlx9 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70orlx9 ] . + +_:node1f3n70orlx9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case2/report.ttl index 3bcec559b1a..7556cc8e4d7 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case2/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case2/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; - sh:focusNode ex:validPerson1; + sh:focusNode ex:Person; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70ot7x9 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70ot7x9 + ], [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70ot7x9 ] . + +_:node1f3n70ot7x9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case3/report.ttl index 3bcec559b1a..93f12ffaffe 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case3/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case3/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; - sh:focusNode ex:validPerson1; + sh:focusNode ex:Person; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70oupx9 + ], [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70oupx9 ] . + +_:node1f3n70oupx9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/report.ttl new file mode 100644 index 00000000000..9d29fd5edf8 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case4/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p0dx9 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p0dx9 + ] . + +_:node1f3n70p0dx9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/report.ttl new file mode 100644 index 00000000000..669bebba647 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case5/report.ttl @@ -0,0 +1,34 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p23x9 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p23x9 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p23x9 + ] . + +_:node1f3n70p23x9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.ttl new file mode 100644 index 00000000000..9b923490010 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/initialData.ttl @@ -0,0 +1,9 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix rsx: . + diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/query1.rq similarity index 100% rename from core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/query1.rq rename to core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/query1.rq diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/report.ttl new file mode 100644 index 00000000000..ed01ba12e54 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/invalid/case6/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p3px9 + ], [ a sh:ValidationResult; + sh:focusNode "purple"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n70p3px9 + ] . + +_:node1f3n70p3px9 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case1/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case2/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValue/targetShapeOr/valid/case3/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case1/report.ttl index 3bcec559b1a..83346063c3a 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case1/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case1/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6e1x12 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6e1x12 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6e1x12 ] . + +_:node1f3n7e6e1x12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case2/report.ttl index 3bcec559b1a..93591aea698 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case2/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case2/report.ttl @@ -4,17 +4,31 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6fjx12 + ], [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6fjx12 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6fjx12 ] . + +_:node1f3n7e6fjx12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case3/report.ttl index 3bcec559b1a..cf76110b397 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case3/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case3/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6h5x12 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6h5x12 ] . + +_:node1f3n7e6h5x12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case4/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case4/report.ttl index 3bcec559b1a..8fcf628e486 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case4/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case4/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:validPerson1; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6ikx12 + ], [ a sh:ValidationResult; + sh:focusNode ex:b; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6ikx12 ] . + +_:node1f3n7e6ikx12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case5/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case5/report.ttl index 37b76113076..4900c3a060c 100644 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case5/report.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case5/report.ttl @@ -4,17 +4,25 @@ @prefix sh: . @prefix rdf: . @prefix rdfs: . +@prefix rsx: . [] a sh:ValidationReport; - sh:conforms false; false; + sh:conforms false; sh:result [ a sh:ValidationResult; sh:focusNode ex:a; sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6k3x12 + ], [ a sh:ValidationResult; + sh:focusNode ex:validPerson1; + sh:resultPath ex:info2; sh:resultSeverity sh:Violation; - sh:sourceShape [ a sh:PropertyShape; - sh:path ex:info2; - sh:minCount 1 - ] + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6k3x12 ] . + +_:node1f3n7e6k3x12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/query1.rq new file mode 100644 index 00000000000..87aafac2538 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/query1.rq @@ -0,0 +1,14 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 a ex:Person ; + ex:info2 "abc". + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/report.ttl new file mode 100644 index 00000000000..f759fb25fc7 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case6/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6lix12 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6lix12 + ] . + +_:node1f3n7e6lix12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/query1.rq new file mode 100644 index 00000000000..229674e80f0 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/query1.rq @@ -0,0 +1,15 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 a ex:Person ; + ex:info "blue" ; + ex:info2 "abc". + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/report.ttl new file mode 100644 index 00000000000..9e9b38b1495 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case7/report.ttl @@ -0,0 +1,34 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode "blue"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6n1x12 + ], [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6n1x12 + ], [ a sh:ValidationResult; + sh:focusNode "abc"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6n1x12 + ] . + +_:node1f3n7e6n1x12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/query1.rq b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/query1.rq new file mode 100644 index 00000000000..bcc99129a49 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/query1.rq @@ -0,0 +1,14 @@ + +PREFIX ex: +PREFIX owl: +PREFIX rdf: +PREFIX rdfs: +PREFIX sh: +PREFIX xsd: + +INSERT DATA { + +ex:validPerson1 a ex:Person ; + ex:info "purple" . + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/report.ttl new file mode 100644 index 00000000000..2c0b54be289 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/invalid/case8/report.ttl @@ -0,0 +1,28 @@ +@prefix ex: . +@prefix foaf: . +@prefix xsd: . +@prefix sh: . +@prefix rdf: . +@prefix rdfs: . +@prefix rsx: . + +[] a sh:ValidationReport; + false; + sh:conforms false; + sh:result [ a sh:ValidationResult; + sh:focusNode ex:Person; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6ogx12 + ], [ a sh:ValidationResult; + sh:focusNode "purple"; + sh:resultPath ex:info2; + sh:resultSeverity sh:Violation; + sh:sourceConstraintComponent sh:MinCountConstraintComponent; + sh:sourceShape _:node1f3n7e6ogx12 + ] . + +_:node1f3n7e6ogx12 a sh:PropertyShape; + sh:minCount 1; + sh:path ex:info2 . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case1/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case2/report.ttl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/initialData.ttl deleted file mode 100644 index deb5dc37855..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/initialData.ttl +++ /dev/null @@ -1,10 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . -@prefix rsx: . - - ex:info2 "1" . diff --git a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/report.ttl b/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/report.ttl deleted file mode 100644 index 246488436f8..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/hasValueIn/targetShapeOr/valid/case3/report.ttl +++ /dev/null @@ -1,6 +0,0 @@ -@prefix ex: . -@prefix foaf: . -@prefix xsd: . -@prefix sh: . -@prefix rdf: . -@prefix rdfs: .