On Friday, August 1, 2014 1:22:15 AM UTC-5, Holger Knublauch
wrote:
I'm working with spin constraints (spin
1.4.0 via Maven). I have them firing but I'm confused
about how to label them so I can see which constraint
has failed. The full code (and data) is at
https://github.com/jameshowison/softcite
(
This is very cool. I am glad to see more projects using
SPIN, some of them with Turtle files edited by hand. If you
do edit these files by hand, I would still recommend to make
them easier to open with TopBraid (Free Edition) and similar
RDF tools. All you would need to do is add some owl:Ontology
into every file and define explicit owl:imports so that when
you load the example file, it will pull all other necessary
files into TopBraid. This may help you get more feedback
because more people could understand what's going on
(without stepping through Java code). Just an idea.
Hey, SPIN is cool, I was very glad to find it. I've
messed around with SWRL a while back, but given that I
vaguely understand SPARQL this is much, much, easier.
If you do edit these files by hand, I would still
recommend to make them easier to open with TopBraid (Free
Edition) and similar RDF tools. All you would need to do is
add some owl:Ontology into every file and define explicit
owl:imports so that when you load the example file, it will
pull all other necessary files into TopBraid. This may help
you get more feedback because more people could understand
what's going on (without stepping through Java code). Just
an idea.
I've created a new branch for my attempt to do this:
It's a little complicated by the need to "drop out" to
some Java code to do some name mapping (some of the programs
that I'm writing data about have alternative names), quite
likely this can be done via SPIN but it isn't at the moment.
If I understand correctly, I should have a "main file" of
rdf that imports the other files? Would one typically do a
vocab file as the main file, then import the individuals and
the spin rules and constraints? At present I've just add
the owl imports for SPIN etc and opened my
SPINConstraints.ttl file in TopBraid FE. In the SPIN
overview tab I see only the constraint for
bioj:ArticleSoftwareLink, but not the constraints
for bioj:SoftwarePackage (which are all spl:Attribute).
may be some local paths in there, sorry!)
and I run the constraints via mvn -Dtest=AppTest#
testSPINConstraints
test
I'm using the output code from the Kennedy's
example, edited to use getCustomizedLabel rather than
getLabel (although using just getLabel doesn't work as
I'd expect either):
for(ConstraintViolation cv : cvs) {
System.out.println("
- at " + SPINLabels.get().getCustomizedLabel(cv.getRoot())
+ ": " + cv.getMessage());
I've tried to follow the code through
cv.getMessage() but I got lost in abstract
interfaces somewhere :)
This is the constraint:
bioj:SoftwareMention a rdfs:Class ;
spin:constraint
[ a spl:Attribute ;
rdfs:comment "Must have one and
exactly one classification "^^xsd:string ;
spl:predicate
citec:mention_category ;
spl:minCount 1 ;
spl:maxCount 1 ;
# spl:valueType
citec:MentionClassification ;
# spl:defaultValue ex:Red
] ;
.
Originally I was working with 1.3.1 and I was
getting the Resource ID but no message:
- at citec:a2007-36-BMC_PLANT_BIOL-B03-mention:
Now I've upgraded to 1.4.0 and I'm getting a
generic message (progress!):
- at citec:a2007-36-BMC_PLANT_BIOL-B03-mention:
Attribute citec:mention_category : [1,1]
Yes I had fixed this bug in 1.3.3 because several users
complained that the message was empty. It now behaves more
consistently with TopBraid. If the template has a
spin:labelTemplate then it will use that.
Hmmm, I think I understand, but the spin:labelTemplate
wouldn't be something that I would define, would it? Perhaps
the spin:labelTemplate defines how the cv.getMessage should be
constructed?
But how would I output the rdfs:comment from the
constraint?
I see that TopBraid also creates the spin:constraints as I
have, but the rdfs:comment doesn't output when running the
cv.getMessage() code? For:
spin:constraint [ a spl:Attribute ;
rdfs:comment "Does this show
up?"^^xsd:string ;
spl:maxCount 1 ;
spl:minCount 1 ;
spl:predicate rdfs:label
] ;
I get - at bioj:a2009-51-MOL_THER-BioEdit: Attribute
rdfs:label : [1,1]
I guess what I expect is:
- at bioj:a2009-51-MOL_THER-BioEdit: Attribute rdfs:label
: [1,1] Does this show up?
which I think is just a matter of adding the content of the
rdfs:comment on the spin:constraint?
As a secondary, but likely related question, I have
this constraint:
bioj:ArticleSoftwareLink a rdfs:Class ;
spin:constraint
[ a sp:Ask ;
sp:text """
# Can only find versions if they exist
ASK WHERE {
?this a bioj:ArticleSoftwareLink ;
citec:has_version_indicator false ;
citec:version_is_findable true .
}"""
] ;
.
That outputs the generic:
- at bioj:a2003-44-BBA-GEN_SUBJECTS-SWISS-MODEL:
SPIN constraint at bioj:ArticleSoftwareLink
But I'd like it to output the comment in the query
( # Can only find versions if they exist ), I
understand that the sp:text gets parsed and that
should end up as an rdfs:comment property on the
constraint, not sure if that's actually right.
In the SPIN RDF syntax (without sp:text), the RDF syntax
tree would have an rdfs:comment triple at the sp:Ask. So you
could try to move the # into an rdfs:comment triple and see
if it works better. It is difficult to rely on the # comment
in the sp:text syntax because this information is thrown
away by the SPARQL parser. The sp:Ask object is there to
allow to attach exactly that kind of explicit metadata.
Right, got yah, I had thought that the sp:text would be
converted to the sp:Ask SPIN RDF first and so the comment
would go to the rdfs:label. I like the sp:text a lot because
I can copy and paste the queries as I work them up in a SPARQL
engine or use them in other pieces of code.
I would also suggest
you switch to CONSTRUCT, which gives you more options,
especially to also specify a spin:violationPath. When you
CONSTRUCT the spin:ConstraintViolation, you can freely chose
an rdfs:label, and that label could be the result of your
own CONCAT string operations in the WHERE clause.
Nice. I'll try that. Ok, going the constraint CONSTRUCT
route gives me the expected message (the content of the
rdfs:label of the ConstraintViolation.)
spin:constraint
[ a sp:Construct ;
sp:text """
CONSTRUCT {
_:violation a spin:ConstraintViolation ;
spin:violationRoot ?this ;
spin:violationPath
citec:version_is_findable ;
rdfs:label "Can only find versions
if they exist"
}
WHERE {
?this
a bioj:ArticleSoftwareLink ;
citec:has_version_indicator false ;
citec:version_is_findable true .
}"""
] ;
outputs:
- at bioj:a2003-44-BBA-GEN_SUBJECTS-SWISS-MODEL: Can only
find versions if they exist
That's great, although FWIW I find it confusing that the
rdfs:label of the ConstraintViolation created in this way
outputs from cv.getMessage() but that other constraints like
sp:Ask or spl:Attribute don't output either their rdfs:comment
or their rdfs:label through the java cv.getMessage() call.
Seems a bit confusing that CONSTRUCT ConstraintViolations are
treated differently in their Messages than (what I presume
are) ConstraintViolations created in other ways. FWIW, the
docs suggest that rdfs:comment (rather than rdfs:label) is
where the human readable description of the purpose of the
spin:constraint should go.
In any case (and perhaps more confusingly) I'd
tried having the comment as rdfs:comment or rdfs:label
for the constraint, but having either of those there
produces a NullPointerException:
java.lang.NullPointerException
at
org.topbraid.spin.util.JenaUtil.getStringProperty(JenaUtil.java:617)
at
org.topbraid.spin.system.SPINLabels.getCustomizedLabel(SPINLabels.java:57)
at
edu.utexas.ischool.jhowison.TTLRepository.runSPINconstraints(TTLRepository.java:523)
The NullPointer is because the ConstraintViolation has no
root resource, so this problem is IMHO unrelated to the
constraint violation's message.
Righto, I'd have thought that the root resource would be
the individual that violated the constraint?
I will try look into
your example more next week, as it is quite possible that
you are pointing at things to improve. Meanwhile: would it
be possible for you to make the files a bit more
TopBraid-friendly so that they are easier to open and study?
I played around a little trying to make a minimal example
from scratch in Top Braid FE, but ran out of time. As I wrote
up top, just adding the imports doesn't seem to work that
well. Appreciate your help, happy to make changes but a
little lost as to how to make these Top Braid friendly.
Thanks,
Holger
--