does negation draw from partition?
What do people mean by ! in a triple pattern?
I propose that it is that there are no corresponding triples in the neighborhood (as opposed to the partition). For instance:
<S> {
(foaf:name . | foaf:givenName .; foaf:familyName ); # either a name or components
foaf:shoeSize .;
(foaf:homepage .; ! foaf:name .)? # no foaf:homepage if there's a foaf:name.
}
would pass
<s> foaf:name "Bob"; foaf:homepage <http://...> .
if negation draws from the partition but fail if it draws from the neighborhood.
IMO, the author's intent is that it fail.
There are other ways of expressing this, e.g.
<S> {
( foaf:name .; foaf:homepage .?
| foaf:givenName .; foaf:familyName );
foaf:shoeSize .
}
but they require reordering the properties which is a problem for e.g. FHIR where we use the order to convert RDF to an ordered XML document.
I believe this is easy to document and implement, but let me know if you disagree. See matches TripleConstraint
In the previous example, you forgot the foaf:shoeSize, right?
I was trying to replicate it but I found a simpler example for which I have some doubts.
Let :S be:
:S { :p [1 2 3]+; !:q [4 5 6] }
and the following data:
:x1 :p 1; :q 4 . # Fail
:x2 :p 1; :q 7 . # Pass
:x3 :p 1; :q 7; :r 1 . # Pass
:x4 :p 1 . # I think it should pass, do you agree?
:x5 :p 1; :r 1 . # The same as before
Do you agree with all those cases?
At this moment, in my implementation, I have a doubt with :x4 and :x5, the problem is that if I model the regular expression of :S as C1; C2 where C1 is :p [1 2 3] and C2 is !q [4 5 6], then :x4 wouldn't match.
All of your tests make sense to me. I think negated TripleConstraints simply do not participate in the partition. It seems like that should work for x4 and x5.
The current negation tests don't appear to conflict with this:
| test | ? | shape | data |
|---|---|---|---|
| 1negateddot_pass-empty | p | <S1>{! <p1>.} |
{ } |
| 1negateddot_pass-missing | p | <S1>{! <p1>.} |
{ <s> <p2> <o1> } |
| 1negateddot_fail-noOthers | f | <S1>{! <p1>.} |
{ <s1> <p1> <o1> } |
| 1negateddot_fail-others_lexicallyEarlier | f | <S1>{! <p1>.} |
{ <s> <p0> <o0>; <p1> <o1> } |
| 1negateddot_fail-others_lexicallyLater | f | <S1>{! <p1>.} |
{ <s> <p1> <o1>; <p2> <o2> } |
| 1negatedinversedot_pass-empty | p | <S1>{!^<p1>.} |
{ } |
| 1negatedinversedot_pass-missing | p | <S1>{!^<p1>.} |
{ <s> <p2> <o1> } |
| 1negatedinversedot_fail-noOthers | f | <S1>{!^<p1>.} |
{ <s1> <p1> <o1> } |
| 1negatedinversedot_fail-others_lexicallyEarlier | f | <S1>{!^<p1>.} |
{ <s> <p0> <o0>; <p1> <o1> } |
| 1negatedinversedot_fail-others_lexicallyLater | f | <S1>{!^<p1>.} |
{ <s> <p1> <o1>; <p2> <o2> } |
And what about the following?
| shape | data |
|---|---|
<S1> { (<p> . | <q> . ); (<r> . ; !<p> . )?} |
{ <x> <p> 1 ; <r> 1 } |
In my implementation it currently passes. Do you expect it to fail?
It is a simplified version of your original example where <p>=foaf:name, <q>=foaf:firstname .; foaf:lastname . and <r>=foaf:homePage .
I added language-suggestion because we currently don't have negation.
(You can meet many negativity use cases with card 0 ({0}).)
I was trying to replicate your original examples and I think they could be represented as:
:User {
( schema:name . |
schema:firstName . ; schema:lastName .
) ;
schema:shoeSize xsd:integer
} AND NOT {
schema:name . ; schema:homePage .
}
which could also be represented as:
:User {
( schema:name . ; schema:homePage . {0,0}
| schema:firstName . ; schema:lastName .; schema:homePage . ?
) ;
schema:shoeSize xsd:integer
}