Re: Simple example of need for negation operator

Bob MacGregor wrote:
> Hi Lee,
> 
> Your example does the job.  I have to congratulate you on your 
> proficiency.  I do
> have a couple of questions.  One, the construct you are using is doing a max
> computation.  The (much simpler) construct I used did not (and there is 
> no max
> in the conceptualization of the quuery).  Also, when your
> example executes, there will be a small cross product computed between the
> different tags attached to each article.  In my example, its a linear 
> scan.  I'm
> wondering if it the cross product is necessary in SPARQL, or if there is 
> another
> way to capture this example that is more efficient and closer to the 
> true semantics
> of the query.

Implementations are free to execute the query however they see fit, as 
long as they produce the correct answer bindings. This could include 
detecting constructs such as these and translating them to (e.g.) 
min/max SQL calls.

I don't know a way to write the query in SPARQL w/o making use of the 
cross-product approach.

> Second, I'm wondering about the general case of universal 
> quantification.  A
> simple example would be something like  "select people all of whose children
> are male".  I'm being lazy here, since I could search  the sparql-dev 
> threads
> looking for the solution.  Do you have one at your fingertips that you 
> can point
> me to?  In our language, this would be
> 
> select ?person
> from model
> where (?person rdf:type Person) AND
>           UNSAID ((?person hasChild ?child) AND
>                         UNSAID (?child gender "Male"))

it's the same style trick, just with a couple of subtleties.

PREFIX : <http://example.org/>
SELECT DISTINCT ?person
FROM <http://thefigtrees.net/lee/sw/data/gender.ttl>
WHERE {
   ?person a :Person .
   OPTIONAL {
     ?person :child ?child .
     ?child :gender ?gender .
     OPTIONAL {
       ?person :child ?otherchild .
       ?otherchild :gender ?othergender .
       FILTER(?gender = "male" && ?otherchild != ?child) .
     }
     FILTER(!bound(?otherchild) || ?othergender = "male")
   }
   FILTER((!bound(?child) || ?gender = "male")
}

test data (at the URL above):

@prefix : <http://example.org/> .

:noChildrenOk a :Person .
:oneMaleChildOk a :Person ; :child [ :gender "male" ] .
:twoMaleChildrenOk a :Person ; :child [ :gender "male" ], [ :gender 
"male" ] .
:oneFemaleChildNotOk a :Person ; :child [ :gender "female" ] .
:mixedChildrenNotOk a :Person ; :child [ :gender "male" ], [ :gender 
"female" ] .
:twoFemaleChildrenNotOk a :Person ; :child [ :gender "female" ], [ 
:gender "female" ] .


results (again, you can test this at http://sparql.org)

?person:
         <http://example.org/twoMaleChildrenOk>
         <http://example.org/oneMaleChildOk>
         <http://example.org/noChildrenOk>


Again, definitely not pretty or easy, but doable.

hope this helps,
Lee


> Cheers, Bob
> 
> 
> On Dec 10, 2007 11:24 PM, Lee Feigenbaum <lee@thefigtrees.net 
> <mailto:lee@thefigtrees.net>> wrote:
> 
>     Bob MacGregor wrote:
>      > Hi Lee,
>      >
>      > OK, we'll try sparql dev, as long as this is a how to, rather than a
>      > "can't be
>      > done".  But it looks to me like
>      > your query returns no bindings if an article does not have a
>     timetag.  I
>      > say this because of the {?a ex:timetag ?maxtime} clause
>      > that comes before the OPTIONAL.  But in that case, it should return
>      > the article.  Can you fix this, or is it not expressible after all?
> 
>     Right, I did that purposefully to concentrate on the "max" idiom. If you
>      want to include articles with no timetag, it becomes:
> 
>     PREFIX : <http://example.org/>
>     SELECT ?a
>     FROM <http://thefigtrees.net/lee/sw/data/times.ttl
>     <http://thefigtrees.net/lee/sw/data/times.ttl>>
>     WHERE {
>       ?a a :article .
>       OPTIONAL {
>         ?a :timetag ?maxtime .
>         OPTIONAL {
>           ?a :timetag ?othertime . FILTER(?othertime > ?maxtime)
>         }
>         FILTER (!bound(?othertime))
>       }
>       FILTER(!bound(?maxtime) || ?maxtime < 5)
>     }
> 
>     The key is, I guess, to make the whole "find the max time" part optional
>     and then filter outside that on "there is no maxtime or the maxtime is
>     early enough".
> 
>     (Note, I put some actual data at the above URL so that you can try this
>     out. To do this I changed the predicate names a bit and used integers
>     instead of datetimes for simplicity. I made "now" equal to 5. :-) ARQ
>     deployed at http://sparql.org is a great place to try it.)
> 
>     The data is:
> 
>     @prefix : <http://example.org/ > .
> 
>     :onetimeOK a :article ; :timetag 1 .
>     :onetimeNotOK a :article ; :timetag 10 .
>     :twotimesOK a :article ; :timetag 1, 2 .
>     :twotimesNotOK a :article ; :timetag 1, 10 .
>     :notimeOK a :article .
> 
> 
>     ... and when I run the above query through ARQ at sparql.org
>     <http://sparql.org> I get:
> 
>     a:
>             <http://example.org/notimeOK <http://example.org/notimeOK>>
>             <http://example.org/twotimesOK>
>             <http://example.org/onetimeOK >
> 
> 
>     Lee
> 
>      >
>      >
>      >     In SPARQL, this query is (unedited, untested):
>      >
>      >     SELECT ?a
>      >     FROM :model
>      >     WHERE {
>      >       ?a rdf:type ft:article ; ex:timetag ?maxtime .
>      >       OPTIONAL { ?a ex:timetag ?othertime . FILTER(?othertime >
>     ?maxtime) }
>      >       FILTER (!bound(?othertime) && ?maxtime > '...now...')
>      >     }
>      >
>      >     Original target:
>      >
>      >
>      > SELECT ?a
>      > FROM model
>      > WHERE
>      >      (?a rdf:type ft:Article) AND
>      >      UNSAID ((?a ex:timetag ?time) AND
>      >                    (?time > $NOW))
>      >
>      > =====================================
>      > Robert MacGregor
>      > Chief Scientist
>      > Siderean Software, Inc.
>      > bob.macgregor@gmail.com <mailto:bob.macgregor@gmail.com>
>     <mailto:bob.macgregor@gmail.com <mailto:bob.macgregor@gmail.com>>
>      > Mobile: 310-469-2810
>      > =====================================
> 
> 
> 
> 
> -- 
> =====================================
> Robert MacGregor
> Chief Scientist
> Siderean Software, Inc.
> bob.macgregor@gmail.com <mailto:bob.macgregor@gmail.com>
> Mobile: 310-469-2810
> =====================================

Received on Tuesday, 11 December 2007 17:20:55 UTC