Re: UNSAID drafted and mapped to SQL

On Fri, Dec 10, 2004 at 06:45:52PM +0000, Seaborne, Andy wrote:
> 
> 
> 
> Eric Prud'hommeaux wrote:
> >In response to a thread on UNSAID in the comments list [1], I've
> >drafted a section on UNSAID [2]. Andy asked about implementing it on
> >an SQL-accessed triple store. I thought I'd share the answer with the
> >WG. I test for default negation by doing an outer join to the triple
> >in the positive and then constraining that part of that triple is
> >NULL:
> >
> >
> >CREATE TABLE holds (id INTEGER NOT NULL AUTO_INCREMENT,
> >                    s VARCHAR(80), p VARCHAR(80), o VARCHAR(80),
> >                    PRIMARY KEY(id));
> >
> >-- _:a  foaf:name              "Alice" .
> >-- _:a  foaf:page              <http://work.example/alice> .
> >-- _:a  foaf:workplaceHomepage <http://work.example/alice> .
> >-- _:b  foaf:name              "Bob" .
> >-- _:c  foaf:name              "Eve" .
> >-- _:c  foaf:page              <http://isp.example/eve> .
> >-- _:c  foaf:workplaceHomepage <http://work.example/eve> .
> >
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:name', '"Alice"');
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:page', 
> >'<http://work.example/alice>');
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:workplaceHomepage', 
> >'<http://work.example/alice>');
> >INSERT INTO holds (s, p, o) VALUES ('_:b', 'foaf:name', '"Bob"');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:name', '"Eve"');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:page', 
> >'<http://isp.example/eve>');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:workplaceHomepage', 
> >'<http://work.example/eve>');
> >
> >-- SELECT ?name
> >--  WHERE  ( ?x foaf:name  ?name )
> >--         UNSAID ( ?x  foaf:mbox  ?mbox ) 
> 
> That is query 1 from the doc but that runs on a different dataset.
> 
> I'm guessing but I think the query should be:
> 
> SELECT ?name
> WHERE  ( ?x foaf:name  ?name )
>        UNSAID ( ?x  foaf:page  ?mbox )
> 
> as the SQL below uses "foaf:page"
> 
> >
> >SELECT h1.o AS name
> >  FROM holds AS h1
> >  LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
> > WHERE h1.p="foaf:name"
> >   AND h2.o IS NULL
> >
> >-- +-------+
> >-- | name  |
> >-- +-------+
> >-- | "Bob" |
> >-- +-------+
> 
> I get this result set.
> 
> If the order is reversed
> 
> i.e.
> 
> SELECT ?name
> WHERE  UNSAID ( ?x  foaf:page  ?mbox )
>        ( ?x foaf:name  ?name )
> 
> I get:
> --------
> | name |
> ========
> --------
> 
> because the UNSAID has a more general pattern (?mbox is unbound so any 
> person with foaf:page is rejected - that's all of them).
> 
> (My query processor executes query in the order written at the moment).
> 
> >
> >-- SELECT ?name ?homepage
> >-- WHERE  ( ?x foaf:name  ?name )
> >--        OPTIONAL { ( ?x  foaf:page  ?homepage ) 
> >--            UNSAID ( ?x  foaf:workplaceHomepage  ?homepage ) }
> >
> >SELECT h1.o AS name, h2.o AS homepage
> >  FROM holds AS h1
> >  LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
> >  LEFT OUTER JOIN holds AS h3 ON h3.s=h1.s AND 
> >  h3.p="foaf:workplaceHomepage" AND h2.o=h3.o
> > WHERE h1.p="foaf:name"
> >   AND h3.o IS NULL
> >
> >-- +-------+--------------------------+
> >-- | name  | homepage                 |
> >-- +-------+--------------------------+
> >-- | "Bob" | NULL                     |
> >-- | "Eve" | <http://isp.example/eve> |
> >-- +-------+--------------------------+
> 
> This is query 2 from the doc on the second dataset.
> 
> I get:
> 
> --------------------------------------
> | name    | homepage                 |
> ======================================
> | "Bob"   |                          |
> | "Alice" |                          |
> | "Eve"   | <http://isp.example/eve> |
> --------------------------------------
> 
> which is different because I get a "Alice" row.
> 
>    ( ?x foaf:name  ?name )
> 
> gets all three people.
> 
> 
> Then,
>    _:a foaf:page <http://work.example/alice>
> matches the first triple pattern of the optional:
>    ( ?x  foaf:page  ?homepage )
> with ?homepage = <http://work.example/alice>
> 
> Then for the UNSAID
>    _:a foaf:workplaceHomepage  <http://work.example/alice>
> exists, UNSAID is false, reject OPTIONAL.  But that leaves ?name = "Alice"
> 
> I expect:
> ( ?x foaf:name  ?name ) OPTIONAL anything
> to pick ?name = "Alice" (and "Bob" and "Eve").
> 
> What ever is in "anything" does not influence outside the OPTIONAL.
> 
> What am I missing?

The fact that I screwed up and didn't try it:

eric@unagi:~/sources/public/perl/modules/W3C/Rdf/bin$ ./algae @../test/SPARQL-UNSAID-1-alg.sh
+-------+------------------------+
|   name|                homepage|
|-------|------------------------|
|  "Bob"|                    NULL|
|"Alice"|                    NULL|
|  "Eve"|<http://isp.example/eve>|
+-------+------------------------+

yeah, SQL for this requires thinking of the UNSAID as part of the
OPTIONAL (which I should have picked up before) and moving the
constraint to the report clause, e.g.

SELECT h1.o AS name, if (h2.o=h3.o, NULL, h2.o) AS homepage
  FROM holds AS h1
  LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
  LEFT OUTER JOIN holds AS h3 ON h3.s=h1.s AND h3.p="foaf:workplaceHomepage" AND h2.o=h3.o
 WHERE h1.p="foaf:name";
+---------+--------------------------+
| name    | homepage                 |
+---------+--------------------------+
| "Alice" | NULL                     |
| "Bob"   | NULL                     |
| "Eve"   | <http://isp.example/eve> |
+---------+--------------------------+

> >[1] 
> >http://lists.w3.org/Archives/Public/public-rdf-dawg-comments/2004Nov/thread.html#16
> >[2] http://www.w3.org/2001/sw/DataAccess/rq23/#unsaid
> 

-- 
-eric

office: +81.466.49.1170 W3C, Keio Research Institute at SFC,
                        Shonan Fujisawa Campus, Keio University,
                        5322 Endo, Fujisawa, Kanagawa 252-8520
                        JAPAN
        +1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA
cell:   +1.857.222.5741 (does not work in Asia)

(eric@w3.org)
Feel free to forward this message to any list for any purpose other than
email address distribution.

Received on Saturday, 11 December 2004 00:14:20 UTC