Closed mucaho closed 3 years ago
I believe this is due to standard Jena behavior. RuleUtil will wrap the data graph into a MultiUnion together with the inferred triples. That MultiUnion uses this prefix mapping, which only looks for the empty (default) prefix in the base graph, see the prefix.length() > 0 in PolyadicPrefixMappingImpl in Jena:
@Override public String getNsPrefixURI( String prefix )
{
PrefixMapping bm = getBaseMapping();
String s = bm.getNsPrefixURI( prefix );
if (s == null && prefix.length() > 0)
The philosophical issue behind this is that the default namespace should only apply to the base graph of a MultiUnion. In general, I would strongly discourage the use of default prefixes as some tools or users will mix them up across graphs. As seen above :)
I guess the change that I could make is to add
unionGraph.setBaseGraph(dataModel.getGraph());
to RuleUtil, right after the upper unionGraph is created (line 96 in my version). Are you able to try this out in your environment to confirm this improves things?
I have run this locally and it seems to parse OK afterwards. As stated on #111 I will put this into our local copy before applying the same change to the open source repo in the future.
That's correct, but the next line pm.setNsPrefixes(map); does not delete the "" prefix from the underlying PrefixMapping, if that already defines one. The fix mentioned above does resolve the issue for me though, by setting the base graph.
Are you able to try this out in your environment to confirm this improves things?
Thank you, can confirm, after adding the example as a resource file, adapting the RuleExample
to use it and after adding the proposed changes to RuleUtil
the example seems to pass:
java [...] org.topbraid.shacl.RuleExample
@base <http://example.org/random> .
@prefix : <http://example.com/> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix swa: <http://topbraid.org/swa#> .
@prefix tosh: <http://topbraid.org/tosh#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:TestShape rdf:type sh:NodeShape ;
sh:rule [ rdf:type sh:TripleRule ;
sh:object [ sh:path [ sh:zeroOrMorePath :p ]
] ;
sh:predicate :q ;
sh:subject sh:this
] ;
sh:targetNode :a .
:a :p :b ;
:q :b , :a , :c .
:b :p :c .
Process finished with exit code 0
On current master efc9fcc8bf2047d2e6172301fd42a280629e725f
I have put this on master, and noticed it should have been shapesModel, not dataModel. The latter only worked if both graphs were the same.
I believe this closes the ticket.
I think I have an expansion upon this issue, that may warrant re-opening it:
running on latest version (1.4.2) in windows 10.
Shapes:
@prefix : <https://myprefix.com/someprefix/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:ageshape a sh:NodeShape ;
sh:targetClass :Age ;
sh:property [
sh:maxCount 1 ;
sh:minCount 1 ;
sh:hasValue 24 ;
sh:path ( :hasQuantity :hasNumber ) ]
.
data:
@prefix : <https://myprefix.com/someprefix/> .
:someAge a :Age ;
:hasQuantity [:hasNumber 24] ;
.
Running the shacl validate command returns an error:
PS shacl-1.4.2\bin> .\shaclvalidate.bat -datafile 'synthea_patients_valid.ttl' -shapesfile 'shacl (1).ttl'
Exception in thread "main" org.apache.jena.query.QueryParseException: Line 2, column 1: Unresolved prefixed name: :hasQuantity
at org.apache.jena.sparql.lang.QueryParserBase.throwParseException(QueryParserBase.java:578)
at org.apache.jena.sparql.lang.QueryParserBase.resolvePName(QueryParserBase.java:320)
at org.apache.jena.sparql.lang.arq.ARQParser.PrefixedName(ARQParser.java:6438)
at org.apache.jena.sparql.lang.arq.ARQParser.iri(ARQParser.java:6422)
at org.apache.jena.sparql.lang.arq.ARQParser.PathPrimary(ARQParser.java:3743)
at org.apache.jena.sparql.lang.arq.ARQParser.PathElt(ARQParser.java:3602)
at org.apache.jena.sparql.lang.arq.ARQParser.PathEltOrInverse(ARQParser.java:3630)
at org.apache.jena.sparql.lang.arq.ARQParser.PathSequence(ARQParser.java:3565)
at org.apache.jena.sparql.lang.arq.ARQParser.PathAlternative(ARQParser.java:3544)
at org.apache.jena.sparql.lang.arq.ARQParser.Path(ARQParser.java:3538)
at org.apache.jena.sparql.lang.arq.ARQParser.VerbPath(ARQParser.java:3493)
at org.apache.jena.sparql.lang.arq.ARQParser.PropertyListPathNotEmpty(ARQParser.java:3418)
at org.apache.jena.sparql.lang.arq.ARQParser.TriplesSameSubjectPath(ARQParser.java:3365)
at org.apache.jena.sparql.lang.arq.ARQParser.TriplesBlock(ARQParser.java:2512)
at org.apache.jena.sparql.lang.arq.ARQParser.GroupGraphPatternSub(ARQParser.java:2425)
at org.apache.jena.sparql.lang.arq.ARQParser.GroupGraphPattern(ARQParser.java:2387)
at org.apache.jena.sparql.lang.arq.ARQParser.WhereClause(ARQParser.java:858)
at org.apache.jena.sparql.lang.arq.ARQParser.AskQuery(ARQParser.java:719)
at org.apache.jena.sparql.lang.arq.ARQParser.Query(ARQParser.java:43)
at org.apache.jena.sparql.lang.arq.ARQParser.QueryUnit(ARQParser.java:22)
at org.apache.jena.sparql.lang.ParserARQ$1.exec(ParserARQ.java:48)
at org.apache.jena.sparql.lang.ParserARQ.perform(ParserARQ.java:95)
at org.apache.jena.sparql.lang.ParserARQ.parse$(ParserARQ.java:52)
at org.apache.jena.sparql.lang.SPARQLParser.parse(SPARQLParser.java:33)
at org.apache.jena.query.QueryFactory.parse(QueryFactory.java:144)
at org.topbraid.jenax.util.ARQFactory.doCreateQuery(ARQFactory.java:201)
at org.topbraid.jenax.util.ARQFactory.createQuery(ARQFactory.java:215)
at org.topbraid.shacl.arq.SHACLPaths.getJenaPath(SHACLPaths.java:260)
at org.topbraid.shacl.engine.Shape.<init>(Shape.java:109)
at org.topbraid.shacl.engine.ShapesGraph.lambda$getShape$1(ShapesGraph.java:201)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1740)
at org.topbraid.shacl.engine.ShapesGraph.getShape(ShapesGraph.java:201)
at org.topbraid.shacl.validation.ValidationEngine.validateNodesAgainstShape(ValidationEngine.java:523)
at org.topbraid.shacl.validation.PropertyConstraintExecutor.executeHelper(PropertyConstraintExecutor.java:60)
at org.topbraid.shacl.validation.PropertyConstraintExecutor.executeConstraint(PropertyConstraintExecutor.java:47)
at org.topbraid.shacl.validation.ValidationEngine.validateNodesAgainstConstraint(ValidationEngine.java:629)
at org.topbraid.shacl.validation.ValidationEngine.validateShapes(ValidationEngine.java:582)
at org.topbraid.shacl.validation.ValidationEngine.validateAll(ValidationEngine.java:482)
at org.topbraid.shacl.validation.ValidationUtil.validateModel(ValidationUtil.java:122)
at org.topbraid.shacl.validation.ValidationUtil.validateModel(ValidationUtil.java:103)
at org.topbraid.shacl.tools.Validate.run(Validate.java:59)
at org.topbraid.shacl.tools.Validate.main(Validate.java:48)
I generally try to avoid using the default prefix, but this is not a sustainable solution - given the fact that empty prefix is a valid component of rdf/ttl serialization. If there is no fix, I have to switch to using Jena shacl for some clients which use the empty prefix, which I would love to avoid since I really like this CLI version.
@rmfranken - your example needs a triple-backtick to box it.
It also means whoever has GH handle 'prefix' doesn't get notifications!
Sorry for the delay. Fix is on master (hopefully).
For the following minimum reproducible example:
Running
$ ./shaclinfer.sh -datafile data_shapes_file.ttl
produces the following exception:This seems like a bug, since I would expect the blank prefix to work like in all other constructs.
For reference and as a control test, changing this to a non-blank prefix:
fixes the issue
$ ./shaclinfer.sh -datafile data_shapes_file.ttl
:I am running the latest SHACL API v1.3.2 on x64 linux.