How to define a SPIN rule? - sparql

I am using AllegroGraph 4.4. I have their sample database input regarding the Kennedy family tree. I have copied an example from their tutorials on SPIN. Here it is:
(ag.spin:register-spin-function
!ex:age
"prefix kennedy: <http://www.franz.com/simple#>
prefix xs: <http://www.w3.org/2001/XMLSchema#>
select ( (2011 - xs:int(?birthYear)) as ?age ) {
?who kennedy:birth-year ?birthYear .
}"
'(?who))
The problem is that I do not know where and how to register this function. I've tried the WebView, but I get this error:
Non-symbol element !ex:age in binding list.
Why do I keep getting this error?
Where should I define the rule?

The code is Common Lisp code that should be part of a source file, or evaluated in the REPL. The error you are getting, ”Non-symbol element !ex:age in binding list” seems to indicate that the system is choking while trying to process !ex:age. Does executing the setup from the example first help? The first line and last lines, (enable-!-reader), and (register-namespace "ex" "http://franz.examples#"), seem like what you would need in order to get !ex:age to be read properly.
(enable-!-reader)
(enable-print-decoded t)
(create-triple-store "kennedy")
(load-ntriples "kennedy.ntriples")
(register-namespace "kennedy" "http://www.franz.com/simple#")
(register-namespace "ex" "http://franz.examples#")

Related

Apache Jena - Is it possible to write to output the BASE directive?

I just started using Jena Apache, on their introduction they explain how to write out the created model. As input I'm using a Turtle syntax file containing some data about some OWL ontologies, and I'm using the #base directive to use relative URI's on the syntax:
#base <https://valbuena.com/ontology-test/> .
And then writing my data as:
<sensor/AD590/1> a sosa:Sensor ;
rdfs:label "AD590 #1 temperatue sensor"#en ;
sosa:observes <room/1#Temperature> ;
ssn:implements <MeasureRoomTempProcedure> .
Apache Jena is able to read that #base directive and expands the relative URI to its full version, but when I write it out Jena doesn't write the #base directive and the relative URI's. The output is shown as:
<https://valbuena.com/ontology-test/sensor/AD590/1> a sosa:Sensor ;
rdfs:label "AD590 #1 temperatue sensor"#en ;
sosa:observes <https://valbuena.com/ontology-test/room/1#Temperature> ;
ssn:implements <https://valbuena.com/ontology-test/MeasureRoomTempProcedure> .
My code is the following:
Model m = ModelFactory.createOntologyModel();
String base = "https://valbuena.com/ontology-test/";
InputStream in = FileManager.get().open("src/main/files/example.ttl");
if (in == null) {
System.out.println("file error");
return;
} else {
m.read(in, null, "TURTLE");
}
m.write(System.out, "TURTLE");
There are multiple read and write commands that take as parameter the base:
On the read() I've found that if on the data file the #base isn't declared it must be done on the read command, othwerwise it can be set to null.
On the write() the base parameter is optional, it doesn't matter if I specify the base (even like null or an URI) or not, the output is always the same, the #base doesn't appear and all realtive URI's are full URI's.
I'm not sure if this is a bug or it's just not possible.
First - consider using a prefix like ":" -- this is not the same as base but makes the output nice as well.
You can configure the base with (current version of Jena):
RDFWriter.create()
.source(model)
.lang(Lang.TTL)
.base("http://base/")
.output(System.out);
It seems that the command used on the introduction tutorial of Jena RDF API is not updated and they show the reading method I showed before (FileManager) which now is replaced by RDFDataMgr. The FileManager way doesn't work with "base" directive well.
After experimenting I've found that the base directive works well with:
Model model = ModelFactory.createDefaultModel();
RDFDataMgr.read(model,"src/main/files/example.ttl");
model.write(System.out, "TURTLE", base);
or
Model model = ModelFactory.createDefaultModel();
model.read("src/main/files/example.ttl");
model.write(System.out, "TURTLE", base);
Although the model.write() command is said to be legacy on RDF output documentation (whereas model.read() is considered common on RDF input documentation, don't understand why), it is the only one I have found that allows the "base" parameter (required to put the #base directive on the output again), RDFDataMgr write methods don't include it.
Thanks to #AndyS for providing a simpler way to read the data, which led to fix the problem.
#AndyS's answer allowed me to write relative URIs to the file, but did not include the base in use for RDFXML variations. To get the xml base directive added correctly, I had to use the following
RDFDataMgr.read(graph, is, Lang.RDFXML);
Map<String, Object> properties = new HashMap<>();
properties.put("xmlbase", "http://example#");
Context cxt = new Context();
cxt.set(SysRIOT.sysRdfWriterProperties, properties);
RDFWriter.create().source(graph).format(RDFFormat.RDFXML_PLAIN).base("http://example#").context(cxt).output(os);

How to compare values, ignoring diacritics, with SPARQL

I've been trying (with no success so far) to filter values with a "broader equals" condition. That is, ignoring diacritics.
select * where {
?s per:surname1 ?t.
bind (fn:starts-with(str(?t),'Maria') as ?noAccent1) .
bind (fn:translate(str(?t),"áéíóú","aeiou") as ?noAccent2) .
} limit 100
To this moment, I've tried with XPath functions fn:contains, fn:compare, fn:translate, fn:starts-with, but none of them seem to be working.
Is there any other way (other than chaining replaces) to add collation into these functions or achieve the same goal?
The XPath functions you mention are not part of the SPARQL standard really, so as you found out, you can't rely on them being supported out of the box (though some vendors may provide them as an add-on).
However, GraphDB (which is based on RDF4J) allows you to create your own custom functions in SPARQL. It is a matter of writing a Java class that implements the org.eclipse.rdf4j.query.algebra.evaluation.function.Function interface, and registering it in the RDF4J engine by packaging it as a Java Service Provider Interface (SPI) implementation.
SPARQL and REGEX do not support efficiently transliterating character maps. If you want an efficient implementation you would need a custom RDF4J custom as described by Jeen.
If you want a quick and dirty solution use this code sample:
PREFIX fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX spif: <http://spinrdf.org/spif#>
select * where {
BIND("Mariana" as ?t) .
BIND("Márénísótú" as ?t2) .
BIND (regex(str(?t),'^Maria') as ?noAccent1) .
BIND (spif:replaceAll(
spif:replaceAll(
spif:replaceAll(
spif:replaceAll(
spif:replaceAll(str(?t2),"á","a"),
"é","e")
,"í","i"),
"ó","o"),
"ú","u") as ?noAccent2) .
}

GeoSPARQL within query

I'm struggling with the GeoSPARQL functions. I have two points defined in my ontology. Using this query I get them in my results:
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?what ?met
WHERE {
?what geo:hasGeometry ?met .
FILTER geof:within( ?met ,"ENVELOPE(51.900991, 51.913594, 4.502206, 4.476328)"^^geo:wktLiteral ) .
}
http://www.example.org/POI#Headquater
http://www.example.org/POI#MiddenVanDeBrug
The question is why http://www.example.org/POI#ErasmusBrug is not part of the search result. Should it be possible to search for polygons within an envelop?
Which GeoSPARQL functions are available in Stardog? Any good example resource?
The ontology I use can be found here
The Stardog documentation for GeoSPARQL can be found here. For more specific support, please come visit us at Stardog Community.
I found out that there is an error in the log file of Stardog upon importing the data:
WARN 2017-12-14 08:31:30,989 [XNIO-1 task-24] com.complexible.stardog.spatial.io.StatementSourceGeospatialSource:parse(95): Failed to parse unknown/malformed shape POLYGON((4.476027 51.91137, 4.497099 51.911291, 4.497142 51.905307, 4.75813 51.905201, 4.476027 51.91137 )). Skipping this record
What could be wrong with this polygon?

Path queries in Wikidata endpoint?

Consider the following snippet
ASK WHERE { wd:Q734774 wdt:P31 wd:Q3918. }
This works fine in Wikidata. I want to use some of the path syntax in the this snippet. Specifically I want to limit the number of the times "wdt:P31" used in the path. According to the guidelines this should be the right syntax:
ASK WHERE { wd:Q734774 wdt:P31{,3} wd:Q3918. }
But it's giving me weird error messages. Any ideas?
The final version of SPARQL 1.1 Property Paths lets you do this with the following query --
ASK WHERE
{ wd:Q734774
wdt:P31? / wdt:P31? / wdt:P31?
wd:Q3918
}
For clarity, I've put the full Property Path Predicate (wdt:P31? / wdt:P31? / wdt:P31?) on a separate line between Subject (wd:Q734774) and Object (wd:Q3918). The trailing ? asks for one-or-zero instances of the wdt:P31 predicate, and the / asks for a sequence, so this full path asks for a sequence of zero-or-one-or-two-or-three instances.

How Do I Query Against Data.gov

I am trying to teach myself this weekend how to run API queries against a data source in this case data.gov. At first I thought I'd use a simple SQL variant, but it seems in this case I have to use SPARQL.
I've read through the documentation, downloaded Twinkle, and can't seem to quite get it to run. Here is an example of a query I'm running. I'm basically trying to find all gas stations that are null around Denver, CO.
PREFIX station: https://api.data.gov/nrel/alt-fuel-stations/v1/nearest.json?api_key=???location=Denver+CO
SELECT *
WHERE
{ ?x station:network ?network like "null"
}
Any help would be very much appreciated.
SPARQL is a graph pattern language for RDF triples. A query consists of a set of "basic graph patterns" described by triple patterns of the form <subject>, <predicate>, <object>. RDF defines the subject and predicate with URI's and the object is either a URI (object property) or literal (datatype or language-tagged property). Each triple pattern in a query must therefore have three entities.
Since we don't have any examples of your data, I'll provide a way to explore the data a bit. Let's assume your prefix is correctly defined, which I doubt - it will not be the REST API URL, but the URI of the entity itself. Then you can try the following:
PREFIX station: <http://api.data.gov/nrel...>
SELECT *
WHERE
{ ?s station:network ?network .
}
...setting the PREFIX to correctly represent the namespace for network. Then look at the binding for ?network and find out how they represent null. Let's say it is a string as you show. Then the query would look like:
PREFIX station: <http://api.data.gov/nrel...>
SELECT ?s
WHERE
{ ?s station:network "null" .
}
There is no like in SPARQL, but you could use a FILTER clause using regex or other string matching features of SPARQL.
And please, please, please google "SPARQL" and "RDF". There is lots of information about SPARQL, and the W3C's SPARQL 1.1 Query Language Recommendation is a comprehensive source with many good examples.