Deleting lists.

An attempt at deleting lists in SPARQL 1.1 Update.

There may well be better ways - this was a script built up piece by piece.

Interesting use of INSERT to mark things found - I also used this style 
in debugging WHERE patterns.

Files attached for local testing.

	Andy

== Simple case
in which the lists are the objects of :p

Two steps:
    (1) first delete all the cons cells
    (2) remove the :p triples.

(2) also removes the list of length 0.

------------------
PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX : <http://example.com/data/#>

INSERT DATA {
:x0 :p () .
:x0 :q "abc" .

:x1 :p (1) .
:x1 :q "def" .

:x2 :p (1 2) .
:x2 :q "ghi" .
}

# Delete the cons cells.
DELETE
      { ?z rdf:first ?head ; rdf:rest ?tail . }
WHERE {
        [] :p ?list .
        ?list rdf:rest* ?z .
        ?z rdf:first ?head ;
           rdf:rest ?tail .
        }

# Delete the triples that connect the lists.
DELETE WHERE { ?x :p ?z . }
------------------


== Complex Case
in which the property for the lists is also used for non-lists
and where lists can be unattached to anything.

Process:
(1) Find the starts of the lists, mark these nodes
      A list is either something with rdf:rest or it's rdf:nil.
(2) delete the cons cells.
(3) Delete the connections to the list as marked by (1)
(4) Deal with unconnected lists.
      Find start (a ndoe with rdf:rest but no in-links)
      Find the cons cell chains.
      Delete.


------------------------------
PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX : <http://example.com/data/#>

INSERT DATA {
:x0 :p () .
:x0 :p "String 0" .
:x0 :p [] .

:x1 :p (1) .
:x1 :p "String 1" .
:x1 :p [] .

:x2 :p (1 2) .
:x2 :p "String 2" .
:x2 :p [] .

# A list not connected.
(1 2) .

# Not legal RDF.
# () .

}

# Mark the objects we need to delete at the end
# A list is either () AKA rdf:nil, or has a rdf:rest.

# We do this so we can find the cons cells to delete
# in stage two but leave evidence for the removal of
# the link to the list even if the property is used
# for a non-list.


INSERT { ?list :deleteMe true . }
WHERE {
     ?x :p ?list .
     FILTER (?list = rdf:nil || EXISTS{?list rdf:rest ?z} )
}

# Now delete the cons cells.
DELETE
      { ?z rdf:first ?head ; rdf:rest ?tail . }
WHERE {
        [] :p ?list .
        ?list rdf:rest* ?z .
        ?z rdf:first ?head ;
           rdf:rest ?tail .
        }

# Delete the marked nodes
DELETE
WHERE { ?x :p ?z .
          ?z :deleteMe true .
}

## ------
## Unconnected lists.

DELETE
      { ?z rdf:first ?head ; rdf:rest ?tail . }
WHERE {
        ?list rdf:rest ?z2 .
        FILTER NOT EXISTS { ?s ?p ?list }
        ?list rdf:rest* ?z .
        ?z rdf:first ?head ;
           rdf:rest ?tail .
        }

Received on Tuesday, 1 March 2011 17:15:32 UTC