Skip to content

Instantly share code, notes, and snippets.

@jaw111
Created October 14, 2019 17:38
Show Gist options
  • Save jaw111/1b149fd1111f774a3613f10955686617 to your computer and use it in GitHub Desktop.
Save jaw111/1b149fd1111f774a3613f10955686617 to your computer and use it in GitHub Desktop.
Generate list in SPARQL
prefix : <http://example.com/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix sh: <http://www.w3.org/ns/shacl#>
# insert some sample data
insert data {
#boxes
:red_box a :Box ;
:color "Red" .
:green_box a :Box ;
:color "Green" .
:blue_box a :Box ;
:color "Blue" .
#tubes
:red_tube a :Tube ;
:color "Red" .
:yellow_tube a :Tube ;
:color "Yellow" .
#balls
:red_ball a :Ball ;
:color "Red" .
};
# insert list stub for each unique type-property-object
insert {
?type ?p [ rdf:first ?o ] .
}
where {
select distinct ?type ?p ?o {
?s a ?type ;
?p ?o .
filter (?p != rdf:type)
}
};
# insert rdf:rest links to next value
delete {
?type ?p ?rest .
}
insert {
?b1 rdf:rest ?rest .
}
where {
{
# select the next larger value for each bnode
select ?type ?p ?b1 (min(?o2) as ?next) {
?type <http://example.com/color> ?b1 , ?b2 .
?b1 rdf:first ?o1 .
?b2 rdf:first ?o2 .
filter (?o1 < ?o2)
}
group by ?type ?p ?b1
}
#find the bnode for next value
?type ?p ?rest .
?rest rdf:first ?next .
};
# insert NodeShape and property for value list
delete {
?type ?p ?b .
}
insert {
?type a sh:NodeShape ;
sh:property [
sh:path ?p ;
sh:in ?b ;
] .
}
where {
?type ?p ?b .
?b rdf:first ?o .
};
# insert nil at end of list
insert {
?b rdf:rest rdf:nil .
}
where {
?b rdf:first ?o .
minus {
?b rdf:rest []
}
};
@VladimirAlexiev
Copy link

hi @jaw111!
Nice tricks here (lists are indeed nasty).

But what are you trying to do? It seems to me there's some mistake in how the SHACL is formed:

:Ball   rdf:type     sh:NodeShape ;
        sh:property  [ sh:in    ( "Red" ) ;
                       sh:path  :color
                     ] .

:Box    rdf:type     sh:NodeShape ;
        sh:property  [ sh:in    [ rdf:type     sh:NodeShape ;
                                  rdf:first    "Blue" ;
                                  rdf:rest     () ;
                                  sh:property  [ sh:in    [ rdf:type     sh:NodeShape ;
                                                            rdf:first    "Green" ;
                                                            rdf:rest     () ;
                                                            sh:property  [ sh:in    ( "Red" ) ;
                                                                           sh:path  rdf:rest
                                                                         ]
                                                          ] ;
                                                 sh:path  rdf:rest
                                               ]
                                ] ;
                       sh:path  :color
                     ] .

:Tube   rdf:type     sh:NodeShape ;
        sh:property  [ sh:in    [ rdf:type     sh:NodeShape ;
                                  rdf:first    "Red" ;
                                  rdf:rest     () ;
                                  sh:property  [ sh:in    ( "Yellow" ) ;
                                                 sh:path  rdf:rest
                                               ]
                                ] ;
                       sh:path  :color
                     ] .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment