Sequence in OWL using protege - sequence

I'm trying to define a sequence of action in OWL using protege. I have read the following topics:
Modelling sequence order in OWL-DL ontology
Assigning sequence in OWL using Protege
The problem I have is that an individual can be in different course of action. I hope the following example helps:
I have the class "Action" and class "Course of Action".
For Action I have the following individuals: "Say Hello", "Give Your Name", "Ask a question", "Say Good Bye"
For Course of Action I want to have 2 different sequences:
Say Hello - Give your Name - Say Good Bye
Say Hello - Ask a question - Say Good Bye
"Say Hello" will be linked to two individual by the property hasNext and I will not be able to find the exact course of action. Is it possible to do what I want in OWL?

This is something you can model, but you'll need to distinguish between the actual sequences and the steps within them. This is typically modeled by a linked list. RDFS defines a list vocabulary with rdf:first, rdf:rest and rdf:nil, but you probably don't want to co-opt that terminology in your OWL ontology. Instead, you'd do something like this
:seq1step1 :hasAction :SayHello ;
:hasNextStep :seq1step2 .
:seq1step2 :hasAction :GiveYourName ;
:hasNextStep :seq1step3 .
:seq1step3 :hasAction :SayGoodbye ;
:hasNextStep :emptySeq .
:seq2step1 :hasAction :SayHello ;
:hasNextStep :seq2step2 .
:seq2step2 :hasAction :AskAQuestion ;
:hasNextStep :seq2step3 .
:seq2step3 :hasAction :SayGoodbye ;
:hasNextStep :emptySeq .
This does mean your queries need to be in terms of steps rather than the specific actions, but that's actually necessary because otherwise:
"Say Hello" will be linked to two individual by the property hasNext and I will not be able to find the exact course of action.

Related

Sequence with conditional nodes in OWL

I want to represent a sequence of action in OWL using protege. What I want to be able to represent is statement like : "if this action is true, then the next action is X. If it's false, then the next action is Y". Also I can have several condition in the same sequence of action.
For the moment I can represent simple sequence of action but I can't manage to add those conditionnal nodes.
Example of what I'm doing now :
:seq1step1 :hasAction :SayHello ;
:hasNextStep :seq1step2 .
:seq1step2 :hasAction :GiveYourName ;
:hasNextStep :seq1step3 .
:seq1step3 :hasAction :SayGoodbye ;
I tried to add a property "hasNextStepIfTrue" but then I can't manage to make a Sparql query to get the full sequence because an individual can have the property hasNextStep or also hasNextStepIfTrue so I always end with only a part of the total sequence.
Maybe it is possible to query the full sequence in SPARQL but I can't find how.
Here is a screen of OntoGraf in protege to show what I want to represent.
Thank you !

SPIN representation to SPARQL

Is there an API that could help convert SPIN representation (of a SPARQL query) back to its SPARQL query form?
From:
[ a <http://spinrdf.org/sp#Select> ;
<http://spinrdf.org/sp#where> ( [ <http://spinrdf.org/sp#object> [ <http://spinrdf.org/sp#varName>
"o"^^<http://www.w3.org/2001/XMLSchema#string> ] ;
<http://spinrdf.org/sp#predicate>
[ <http://spinrdf.org/sp#varName>
"p"^^<http://www.w3.org/2001/XMLSchema#string> ] ;
<http://spinrdf.org/sp#subject>
[ <http://spinrdf.org/sp#varName>
"s"^^<http://www.w3.org/2001/XMLSchema#string> ]
] )
] .
To:
SELECT *
WHERE {
?s ?p ?o .
}
Thanks in advance.
I know two jena-based APIs to work with SPIN.
You can use either org.topbraid:shacl:1.0.1 which is based on jena-arq:3.0.4 or the mentioned in the comment org.spinrdf:spinrdf:3.0.0-SNAPSHOT, which is a fork of the first one, but with changed namespaces and updated dependencies.
Note the first (original) API also may work with modern jena (3.13.x), at least your task can be solved in such circumstances.
The second API has no maven release yet, but can be included into your project via jitpack.
To solve the problem you need to find the root org.apache.jena.rdf.model.Resource and cast it to org.topbraid.spin.model.Select (or org.spinrdf.model.Select) using jena polymorphism (i.e. the operation org.apache.jena.rdf.model.RDFNode#as(Class)).
Then #toString() will return the desired query with the model's prefixes.
Note that all personalities are already included into model via static initialization.
A demonstration of this approach is SpinTransformer from ONT-API test-scope, which transforms SPARQL-based queries to an equivalent form with sp:text.

How to Sparql INSERT in TopBraid Composer?

I'm trying to insert new classes by using Sparql in TopBraid Composer (ME 5.5.2). My simple ontology looks like this:
Then I wrote a Sparql query to insert Berry as a subclass of Fruit:
PREFIX ft: <http://www.semanticweb.org/ontologies/2018/7/fruit#>
PREFIX rdfs: <ttp://www.w3.org/2000/01/rdf-schema#>
INSERT
{ft:Berry rdfs:subClassOf ft:Fruit}
But an error message appeared, saying Encountered "insert". Was expecting one of: "base, "select", ...
A similar post: Sparql insert data not working says that Sparql Query is a different language from Sparql Update. Some other post says that Sparql Update is not supported in Protege but is supported in Composer (for which reason I downloaded Composer). I also checked the Composer manual: https://www.topquadrant.com/docs/TBC-Getting-Started-Guide52.pdf, which mentions Sparql Update but doesn't say much.
My question then is, is it possible to insert classes and axioms in TopBraid? If so, how? My end goal is that the inserted classes will appear in the hierarchical view, and their inserted class definitions can be seen on the side as well. If Composer can't do this, what other tools/workflows can I use?
Sorry for such a newbie question. Any help is appreciated.
There are two forms of INSERT in SPARQL 1.1 Update:
INSERT DATA
INSERT
You are mixing them up.
The following works for me in TBC 5.5.2 Free Edition against the kennedys.ttl example:
INSERT DATA
{ kennedys:UralStateUniversity a kennedys:College }
Being an unknown URI, the subject is underlined in query editor, but just press the "Execute SPARQL" button.
Update
In your particular case, you should say something like
INSERT DATA
{ ft:Berry rdfs:subClassOf ft:Fruit; a owl:Class }
Please note that owl:Class is used. TBC considers instances of rdfs:Class as "system classes", their icons are brown, not yellow.

How to create and use GeoSpatial indexes in Marklogic from Sparql

I have loaded the geospatial data from geonames.org into Marklogic using RDF import.
When using the Query Console to explore the data, I see the data has been loaded into an xml document and looks like this:
<sem:triple>
<sem:subject>http://sws.geonames.org/2736540/</sem:subject>
<sem:predicate>http://www.w3.org/2003/01/geo/wgs84_pos#lat</sem:predicate>
<sem:object datatype="http://www.w3.org/2001/XMLSchema#string">40.41476</sem:object>
</sem:triple>
<sem:triple>
<sem:subject>http://sws.geonames.org/2736540/</sem:subject>
<sem:predicate>http://www.w3.org/2003/01/geo/wgs84_pos#long</sem:predicate>
<sem:object datatype="http://www.w3.org/2001/XMLSchema#string">-8.54304</sem:object>
</sem:triple>
I am able to do a SPARQL DESCRIBE and see data. Here is an example.
#prefix geonames: <http://www.geonames.org/ontology#> .
#prefix xs: <http://www.w3.org/2001/XMLSchema#> .
#prefix p0: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
<http://sws.geonames.org/2736540/> geonames:parentCountry <http://sws.geonames.org/2264397/> ;
geonames:countryCode "PT"^^xs:string ;
p0:long "-8.54304"^^xs:string ;
geonames:featureCode <http://www.geonames.org/ontology#P.PPL> ;
geonames:parentADM1 <http://sws.geonames.org/2742610/> ;
geonames:parentFeature <http://sws.geonames.org/2742610/> ;
<http://www.w3.org/2000/01/rdf-schema#isDefinedBy> "http://sws.geonames.org/2736540/about.rdf"^^xs:string ;
a geonames:Feature ;
geonames:locationMap <http://www.geonames.org/2736540/pedreira-de-vilarinho.html> ;
geonames:name "Pedreira de Vilarinho"^^xs:string ;
geonames:nearbyFeatures <http://sws.geonames.org/2736540/nearby.rdf> ;
geonames:featureClass geonames:P ;
p0:lat "40.41476"^^xs:string .
I want to query over this data using SPARQL QUERY as my Query Type in a way where I can take advantage of the geospatial indexes that MarkLogic can create.
I have been having trouble with two aspects of this.
How to correctly create the geospatial indexes for the wgs84_pos#lat and wgs84_pos#long predicates?
How do I access those indexes from SPARQL QUERY?
I would like to have a sparql query that would be able to find subjects within some range of a Point.
=====================================
Followup:
After following David Ennis's Answer (Which worked nicely, thanks!) I ended up with this sample Xquery that was able to select data out of documents via geosearch and then use those IRI's in a sparql values query.
Example:
xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics"
at "/MarkLogic/semantics.xqy";
let $matches := cts:search(//rdf:RDF,
cts:element-pair-geospatial-query (
fn:QName("http://www.geonames.org/ontology#","Feature"),
fn:QName("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat"),
fn:QName ("http://www.w3.org/2003/01/geo/wgs84_pos#","long"),
cts:circle(10, cts:point(19.8,99.8))))
let $iris := sem:iri($matches//#rdf:about)
let $bindings := (fn:map(function($n) { map:entry("featureIRI", $n) }, $iris))
let $sparql := '
PREFIX wgs: <http://www.w3.org/2003/01/geo/wgs84_pos#>
SELECT *
WHERE {
?featureIRI wgs:lat ?lat;
wgs:long ?long.
}
'
return sem:sparql-values($sparql, $bindings)
This xquery queries the geospatial index, finds matching documents and then selects the IRI in the rdf:about attribute of the xml document.
It then maps over all of those IRIs and creates map entries that can be passed in the bindings parameter of the sem:sparql-values function.
I do not believe you can do what you want via just native SPARQL. Geospacial queries in any SPARQL implementation are extensions like geoSPARQL, Apache Jena geospacial queries etc.
My suggested approach in MarkLogic:
Insert the geonames subjects into MarkLogic as unmanaged triples (an XML or JSON document with embedded triples for each one)
In the same document, include the geo-spacial data in one of the acceptable MarkLogic formats. This essentially adds geo-spacial metadata to the triple since it is in the same fragment.
Add geo-spacial path-range-indexes for the geospacial data.
Use SPARQL inside of MarkLogic with a cts query restriction.
The Building Blocks for above:
Understanding unmanaged triples
Understanding Geo-spacial Region Types
Understanding Geo-spacial Indexes
Understanding Geo-spacial Queries
Understanding Semantics with cts search
Another approach to the final query could be the Optic API but I do not see how it would negate the need to do steps 1-3

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.