686 lines
26 KiB
Java
686 lines
26 KiB
Java
package lu.jpt.csparqlproject.rentacar;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.Observable;
|
|
import java.util.Observer;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import eu.larkc.csparql.cep.api.RdfQuadruple;
|
|
import eu.larkc.csparql.cep.api.RdfStream;
|
|
import eu.larkc.csparql.common.RDFTable;
|
|
import eu.larkc.csparql.common.RDFTuple;
|
|
import eu.larkc.csparql.common.utils.CsparqlUtils;
|
|
import eu.larkc.csparql.common.utils.ReasonerChainingType;
|
|
import eu.larkc.csparql.core.engine.CsparqlEngine;
|
|
import lu.jpt.csparqlproject.Main;
|
|
import lu.jpt.csparqlproject.misc.QueryContainer;
|
|
import lu.jpt.csparqlproject.util.WindowLoggingRdfStream;
|
|
|
|
/**
|
|
* This is the main simulation part of the project.
|
|
* It is being run within a separate thread, continously feeding its
|
|
* data into the rdf event streams which are registered with the engine.
|
|
*
|
|
* The simulation itself is not that sophisticated and based on a lot of
|
|
* random numbers.
|
|
*/
|
|
public class RentACarSimulation implements Runnable {
|
|
|
|
public static Logger logger = LoggerFactory.getLogger(RentACarSimulation.class);
|
|
|
|
public static final String BASE_URI = "http://example.org/carSim";
|
|
public static final String BASE_ONTOLOGY_IRI = BASE_URI + "/carSimulationOntology#";
|
|
public static final String BASE_STREAM_IRI = BASE_URI + "/stream";
|
|
public static final String BASE_OBJECT_IRI = BASE_URI + "/objects";
|
|
public static final String CAR_STREAM_IRI = BASE_STREAM_IRI + "/carStream";
|
|
public static final String DRIVER_STREAM_IRI = BASE_STREAM_IRI + "/driverStream";
|
|
public static final String DOMAIN_KNOWLEDGE_GRAPH_IRI = BASE_URI + "/localDomainKnowledge";
|
|
|
|
private CarPool carPool;
|
|
private List<Driver> drivers;
|
|
|
|
private volatile boolean runSimulation;
|
|
private volatile boolean pauseSimulation;
|
|
|
|
private RdfStream carStream;
|
|
private RdfStream driverStream;
|
|
|
|
private CsparqlEngine engine;
|
|
|
|
public RentACarSimulation(CsparqlEngine engine) {
|
|
this.engine = engine;
|
|
this.registerOwnPrefixes();
|
|
int numberOfCars = 2; // Maximum of 10 cars are in the ABox (0-9)
|
|
int numberOfCustomers = 5; // Maximum of 5 drivers are in the ABox (0-4)
|
|
// Create a car pool and drivers
|
|
this.carPool = new CarPool(numberOfCars);
|
|
this.drivers = new ArrayList<Driver>();
|
|
for(int i = 0; i < numberOfCustomers; i++) {
|
|
Driver driver = new Driver(i, this.carPool);
|
|
RentACarSimulation.logger.debug(driver.toString());
|
|
this.drivers.add(driver);
|
|
}
|
|
// Create streams
|
|
this.carStream = new WindowLoggingRdfStream(CAR_STREAM_IRI);
|
|
this.driverStream = new WindowLoggingRdfStream(DRIVER_STREAM_IRI);
|
|
// Green light for simulation
|
|
this.runSimulation = true;
|
|
this.pauseSimulation = false;
|
|
}
|
|
|
|
private void registerOwnPrefixes() {
|
|
Main.prefixManager.registerPrefix("event", RentACarSimulation.BASE_OBJECT_IRI+"/event#");
|
|
Main.prefixManager.registerPrefix("carOnt", RentACarSimulation.BASE_ONTOLOGY_IRI);
|
|
Main.prefixManager.registerPrefix("car", RentACarSimulation.BASE_OBJECT_IRI+"/Car#");
|
|
Main.prefixManager.registerPrefix("driver", RentACarSimulation.BASE_OBJECT_IRI+"/Driver#");
|
|
}
|
|
|
|
public RdfStream getCarStream() {
|
|
return this.carStream;
|
|
}
|
|
|
|
public RdfStream getDriverStream() {
|
|
return this.driverStream;
|
|
}
|
|
|
|
/**
|
|
* All the simulation is happening within its own Thread
|
|
*/
|
|
@Override
|
|
public void run() {
|
|
// Run the simulation as long as needed
|
|
while(this.runSimulation) {
|
|
if(this.pauseSimulation) {
|
|
this.waitForSimulationToResume();
|
|
}
|
|
// A driver will autonomously pick a car, use it for some time and leave it.
|
|
for(Driver driver : this.drivers) {
|
|
driver.tick();
|
|
}
|
|
for(Car car: this.carPool.getCars()) {
|
|
car.tick();
|
|
}
|
|
// Push the new data into the stream(s)
|
|
this.pushDataToStream();
|
|
// Now wait a short while
|
|
try {
|
|
Thread.sleep(1000);
|
|
} catch (InterruptedException e) {
|
|
// We got interrupted, so what.
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Push all the data into the corresponding streams for processing.
|
|
*/
|
|
private void pushDataToStream() {
|
|
for(Driver d : this.drivers) {
|
|
List<RdfQuadruple> quads = d.getQuadruples();
|
|
for(RdfQuadruple q : quads) {
|
|
this.driverStream.put(q);
|
|
}
|
|
}
|
|
for(Car c : this.carPool.getCars()) {
|
|
List<RdfQuadruple> quads = c.getQuadruples();
|
|
for(RdfQuadruple q : quads) {
|
|
this.carStream.put(q);
|
|
}
|
|
}
|
|
}
|
|
|
|
private synchronized void waitForSimulationToResume() {
|
|
try {
|
|
while(this.pauseSimulation) this.wait();
|
|
} catch (InterruptedException e) {
|
|
// No matter what, just wait again.
|
|
}
|
|
}
|
|
|
|
public synchronized void pauseSimulation() {
|
|
this.pauseSimulation = true;
|
|
}
|
|
|
|
public synchronized void resumeSimulation() {
|
|
this.pauseSimulation = false;
|
|
this.notify();
|
|
}
|
|
|
|
/**
|
|
* Tells the simulation to stop
|
|
*/
|
|
public void pleaseStopSimulation() {
|
|
this.runSimulation = false;
|
|
}
|
|
|
|
|
|
private static void setUpReasoningOnQueryContainer(QueryContainer queryContainer) {
|
|
try {
|
|
queryContainer.enableReasoning(
|
|
CsparqlUtils.fileToString("data/rdfs.rules"),
|
|
CsparqlUtils.serializeRDFFile("data/carSimulationTBox.rdf"),
|
|
ReasonerChainingType.HYBRID
|
|
);
|
|
} catch (Exception e) {
|
|
RentACarSimulation.logger.error(e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 1) Query to determine cars that are standing still
|
|
*/
|
|
public QueryContainer getStandingCarsStream() {
|
|
String query = "REGISTER STREAM getStandingCars AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarStandingEvent "
|
|
+ " ; car:relatedCar ?car . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 2s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " FILTER(?speed = 0) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getStandingCars", query, true);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 1) Query to determine cars that are moving
|
|
*/
|
|
public QueryContainer getMovingCarsStream() {
|
|
String query = "REGISTER STREAM getMovingCars AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarMovingEvent "
|
|
+ " ; car:relatedCar ?car . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 2s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " FILTER(?speed > 0) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getMovingCars", query, true);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 2) Query to determine cars that are strongly accelerating
|
|
*/
|
|
public QueryContainer getStronglyAcceleratingCarsStream() {
|
|
String query = "REGISTER STREAM getStronglyAcceleratingCars AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarStrongAcceleratingEvent "
|
|
+ " ; car:relatedCar ?car "
|
|
+ " ; car:deltaSpeed ?deltaSpeed . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e1 rdf:type car:CarStatusEvent . "
|
|
+ " ?e1 car:relatedCar ?car . "
|
|
+ " ?e1 car:speed ?speed1 ."
|
|
+ " ?e2 rdf:type car:CarStatusEvent . "
|
|
+ " ?e2 car:relatedCar ?car . "
|
|
+ " ?e2 car:speed ?speed2 ."
|
|
+ " FILTER NOT EXISTS {"
|
|
+ " ?ex rdf:type car:CarStatusEvent . "
|
|
+ " FILTER(f:timestamp(?e1,rdf:type,car:CarStatusEvent) < f:timestamp(?ex,rdf:type,car:CarStatusEvent)) "
|
|
+ " FILTER(f:timestamp(?ex,rdf:type,car:CarStatusEvent) < f:timestamp(?e2,rdf:type,car:CarStatusEvent)) "
|
|
+ " } "
|
|
+ " BIND(?speed2 - ?speed1 AS ?deltaSpeed) "
|
|
+ " FILTER(f:timestamp(?e1,rdf:type,car:CarStatusEvent) < f:timestamp(?e2,rdf:type,car:CarStatusEvent)) "
|
|
+ " FILTER(?deltaSpeed > 25) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getStronglyAcceleratingCars", query, true);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 2) Query to determine cars that are strongly braking
|
|
*/
|
|
public QueryContainer getStronglyBrakingCarsStream() {
|
|
String query = "REGISTER STREAM getStronglyBrakingCars AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarStrongBrakingEvent "
|
|
+ " ; car:relatedCar ?car "
|
|
+ " ; car:deltaSpeed ?deltaSpeed . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e1 rdf:type car:CarStatusEvent . "
|
|
+ " ?e1 car:relatedCar ?car . "
|
|
+ " ?e1 car:speed ?speed1 . "
|
|
+ " ?e2 rdf:type car:CarStatusEvent . "
|
|
+ " ?e2 car:relatedCar ?car . "
|
|
+ " ?e2 car:speed ?speed2 . "
|
|
+ " FILTER NOT EXISTS {"
|
|
+ " ?ex rdf:type car:CarStatusEvent . "
|
|
+ " FILTER(f:timestamp(?e1,rdf:type,car:CarStatusEvent) < f:timestamp(?ex,rdf:type,car:CarStatusEvent)) "
|
|
+ " FILTER(f:timestamp(?ex,rdf:type,car:CarStatusEvent) < f:timestamp(?e2,rdf:type,car:CarStatusEvent)) "
|
|
+ " } "
|
|
+ " BIND(?speed2 - ?speed1 AS ?deltaSpeed) "
|
|
+ " FILTER(f:timestamp(?e1,rdf:type,car:CarStatusEvent) < f:timestamp(?e2,rdf:type,car:CarStatusEvent)) "
|
|
+ " FILTER(?deltaSpeed < -25) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getStronglyBrakingCars", query, true);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 3) Query to determine engine wear aka higher motor rpms over time
|
|
* than the engine allows (see domain knowledge)
|
|
*/
|
|
public QueryContainer getEngineWearStream() {
|
|
String query = "REGISTER STREAM getEngineWear AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarEngineWearEvent "
|
|
+ " ; car:relatedCar ?car"
|
|
+ " ; car:avgMotorRPM ?avgMotorRPM "
|
|
+ " ; car:maxMotorRPM ?maxMotorRPM . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 3s STEP 1s] "
|
|
+ "FROM <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> "
|
|
+ "WHERE { "
|
|
+ " { "
|
|
+ " SELECT ?car (AVG(?motorRPM) AS ?avgMotorRPM) "
|
|
+ " WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:motorRPM ?motorRPM . "
|
|
+ " } "
|
|
+ " GROUP BY (?car) "
|
|
+ " }"
|
|
+ " ?car car:isCarModel ?carModel . "
|
|
+ " ?carModel car:maximumMotorRPM ?maxMotorRPM . "
|
|
+ " FILTER(?avgMotorRPM > ?maxMotorRPM) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getEngineWear", query, true);
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
queryContainer.useObserverWindow();
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 3) Query to transform the CarStrongBrakingEvent into a
|
|
* CarBrakeWearEvent.
|
|
*/
|
|
public QueryContainer getBrakeWearStream() {
|
|
String query = "REGISTER STREAM getBrakeWear AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarBrakeWearEvent "
|
|
+ " ; car:relatedCar ?car . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.BASE_STREAM_IRI+"/getStronglyBrakingCars> [RANGE 3s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStrongBrakingEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getBrakeWear", query, true);
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 3) Query to create CarHandbrakeWearEvents when cars are moving with their handbrake engaged
|
|
*/
|
|
public QueryContainer getHandbrakeWearStream() {
|
|
String query = "REGISTER STREAM getHandbrakeWear AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarHandbrakeWearEvent "
|
|
+ " ; car:relatedCar ?car . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 3s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:handbrakeEngaged ?handbrakeEngaged . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " FILTER(?speed > 0) "
|
|
+ " FILTER(?handbrakeEngaged = true) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getHandbrakeWear", query, true);
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 3) Query to created CarTireWearEvents when tires run with lower pressure
|
|
* than allowed in domain knowledge.
|
|
* Does not work for some weird reason. Maybe limits of the engine or i overlooked something big.
|
|
* Possible solution: Use something other than xsd:double and try again.
|
|
* Additional note: Switching to xsd:integer did NOT help. Perhaps the query is too long
|
|
* or an internal limit is reached.
|
|
*/
|
|
public QueryContainer getTireWearStream() {
|
|
String query = "REGISTER STREAM getTireWear AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:CarTireWearEvent "
|
|
+ " ; car:relatedCar ?car . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 3s STEP 1s] "
|
|
+ "FROM <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?car car:isCarModel ?carModel . "
|
|
+ " ?carModel car:minimumTirePressure ?minTirePressure . "
|
|
+ " ?e car:tirePressure1 ?tpress1 . "
|
|
+ " ?e car:tirePressure2 ?tpress2 . "
|
|
+ " ?e car:tirePressure3 ?tpress3 . "
|
|
+ " ?e car:tirePressure4 ?tpress4 . "
|
|
+ " FILTER(?speed > 0) "
|
|
+ " FILTER(?tpress1 < ?minTirePressure || ?tpress2 < ?minTirePressure || ?tpress3 < ?minTirePressure || ?tpress4 < ?minTirePressure) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getTireWear", query, true);
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 4) Query to observe in order to update the driver or
|
|
* a car within domain knowledge accordingly.
|
|
* This query takes note of every driver currently driving a vehicle.
|
|
*/
|
|
public QueryContainer getCarTakenEventsQuery() {
|
|
String query = "REGISTER QUERY getCarTakenEvents AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?driver ?car "
|
|
+ "FROM STREAM <"+RentACarSimulation.DRIVER_STREAM_IRI+"> [RANGE 2s TUMBLING] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarTakenEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:relatedUser ?driver . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getCarTakenEvents", query, false);
|
|
final CsparqlEngine engine = this.engine;
|
|
queryContainer.useCustomObserver(new Observer() {
|
|
@Override
|
|
public void update(Observable o, Object arg) {
|
|
RDFTable results = (RDFTable) arg;
|
|
Collection<RDFTuple> tuples = results.getTuples();
|
|
for(RDFTuple tuple : tuples) {
|
|
String driverUri = tuple.get(0);
|
|
String carUri = tuple.get(1);
|
|
String updateQuery = "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "INSERT DATA { "
|
|
+ " GRAPH <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> { "
|
|
+ " <"+driverUri+"> car:drives <"+carUri+"> . "
|
|
+ " <"+carUri+"> car:isDrivenBy <"+driverUri+"> . "
|
|
+ " } "
|
|
+ "}";
|
|
RentACarSimulation.logger.debug(updateQuery);
|
|
engine.execUpdateQueryOverDatasource(updateQuery);
|
|
}
|
|
}
|
|
});
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 4) Query to observe in order to update the driver or
|
|
* a car within domain knowledge accordingly.
|
|
* This query removes all relationships between a driver and a car
|
|
* when the car is being returned.
|
|
*/
|
|
public QueryContainer getCarReturnedEventsQuery() {
|
|
String query = "REGISTER QUERY getCarReturnedEvents AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?driver ?car "
|
|
+ "FROM STREAM <"+RentACarSimulation.DRIVER_STREAM_IRI+"> [RANGE 2s TUMBLING] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarReturnedEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:relatedUser ?driver . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getCarReturnedEvents", query, false);
|
|
final CsparqlEngine engine = this.engine;
|
|
queryContainer.useCustomObserver(new Observer() {
|
|
@Override
|
|
public void update(Observable o, Object arg) {
|
|
RDFTable results = (RDFTable) arg;
|
|
Collection<RDFTuple> tuples = results.getTuples();
|
|
for(RDFTuple tuple : tuples) {
|
|
String driverUri = tuple.get(0);
|
|
String carUri = tuple.get(1);
|
|
String updateQuery = "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "DELETE DATA { "
|
|
+ " GRAPH <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> { "
|
|
+ " <"+driverUri+"> car:drives <"+carUri+"> . "
|
|
+ " <"+carUri+"> car:isDrivenBy <"+driverUri+"> . "
|
|
+ " } "
|
|
+ "}";
|
|
RentACarSimulation.logger.debug(updateQuery);
|
|
engine.execUpdateQueryOverDatasource(updateQuery);
|
|
}
|
|
}
|
|
});
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 5) Query to report all WearEvents using enabled inference.
|
|
* Also returns the responsible driver if available
|
|
*/
|
|
public QueryContainer getWearEvents() {
|
|
String query = "REGISTER STREAM getWearEvents AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?e ?type ?car ?driverName ?driverPhone "
|
|
+ "FROM STREAM <"+RentACarSimulation.BASE_STREAM_IRI+"/getEngineWear> [RANGE 1s TUMBLING] "
|
|
+ "FROM STREAM <"+RentACarSimulation.BASE_STREAM_IRI+"/getBrakeWear> [RANGE 1s TUMBLING] "
|
|
+ "FROM STREAM <"+RentACarSimulation.BASE_STREAM_IRI+"/getHandbrakeWear> [RANGE 1s TUMBLING] "
|
|
+ "FROM STREAM <"+RentACarSimulation.BASE_STREAM_IRI+"/getTireWear> [RANGE 1s TUMBLING] "
|
|
+ "FROM <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarWearEvent . "
|
|
+ " ?e rdf:type ?type . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " OPTIONAL { "
|
|
+ " ?car car:isDrivenBy ?driver . "
|
|
+ " ?driver car:hasName ?driverName . "
|
|
+ " ?driver car:hasPhoneNumber ?driverPhone . "
|
|
+ " } "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getWearEvents", query, true);
|
|
queryContainer.useObserverWindow();
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* 6) Query to report locked cars that move due to forgotten handbrake
|
|
*/
|
|
public QueryContainer getLockedMovingCars() {
|
|
String query = "REGISTER QUERY getLockedMovingCars AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?car "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 15s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?lockEvent rdf:type car:CarLockEvent . "
|
|
+ " ?lockEvent car:relatedCar ?car . "
|
|
+ " ?rollingEvent rdf:type car:CarStatusEvent . "
|
|
+ " ?rollingEvent car:relatedCar ?car . "
|
|
+ " ?rollingEvent car:speed ?speed . "
|
|
+ " ?rollingEvent car:handbrakeEngaged ?handbrake . "
|
|
+ " ?rollingEvent car:locked ?locked . "
|
|
+ " FILTER(?speed>0) "
|
|
+ " FILTER(?locked) "
|
|
+ " FILTER(!?handbrake) "
|
|
+ " FILTER(f:timestamp(?lockEvent,rdf:type,car:CarLockEvent) < f:timestamp(?rollingEvent,rdf:type,car:CarStatusEvent)) "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getLockedMovingCars", query, true);
|
|
queryContainer.useObserverWindow();
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
///////////////////////////////////// UNUSED QUERIES BELOW THIS LINE /////////////////////////////////////
|
|
///////////////////////////////////// UNUSED QUERIES BELOW THIS LINE /////////////////////////////////////
|
|
///////////////////////////////////// UNUSED QUERIES BELOW THIS LINE /////////////////////////////////////
|
|
|
|
public QueryContainer getEventsQuery() {
|
|
String query = "REGISTER QUERY getCarStatusEvents AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?car ?locked ?on ?speed ?rpm ?handbrake ?tirePressure1 ?tirePressure2 ?tirePressure3 ?tirePressure4 "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "FROM STREAM <"+RentACarSimulation.DRIVER_STREAM_IRI+"> [RANGE 15s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:locked ?locked . "
|
|
+ " ?e car:motorOn ?on . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " ?e car:motorRPM ?rpm . "
|
|
+ " ?e car:handbrakeEngaged ?handbrake . "
|
|
+ " ?e car:tirePressure1 ?tirePressure1 . "
|
|
+ " ?e car:tirePressure2 ?tirePressure2 . "
|
|
+ " ?e car:tirePressure3 ?tirePressure3 . "
|
|
+ " ?e car:tirePressure4 ?tirePressure4 . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getCarStatusEvents", query, false);
|
|
queryContainer.useObserverWindow();
|
|
return queryContainer;
|
|
}
|
|
|
|
public QueryContainer getEventUsingBackgroundKnowledge() {
|
|
String query = "REGISTER QUERY getEventsCombinedWithBackgroundKnowledge AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?car ?driverName ?driverPhone "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "FROM STREAM <"+RentACarSimulation.DRIVER_STREAM_IRI+"> [RANGE 15s STEP 1s] "
|
|
+ "FROM <"+RentACarSimulation.DOMAIN_KNOWLEDGE_GRAPH_IRI+"> "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?car car:isDrivenBy ?driver . "
|
|
+ " ?driver car:hasName ?driverName . "
|
|
+ " ?driver car:hasPhoneNumber ?driverPhone . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getEventsCombinedWithBackgroundKnowledge", query, false);
|
|
queryContainer.useObserverWindow();
|
|
return queryContainer;
|
|
}
|
|
|
|
public QueryContainer getSpeedByCar() {
|
|
String query = "REGISTER QUERY getSpeedByCar AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?car ?speed "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ "}";
|
|
QueryContainer queryContainer = new QueryContainer("getSpeedByCar", query, false);
|
|
queryContainer.useObserverWindow();
|
|
return queryContainer;
|
|
}
|
|
|
|
public QueryContainer getAverageDataByCarAsStream() {
|
|
String query = "REGISTER STREAM getAverageSpeedByCar AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "CONSTRUCT { "
|
|
+ " [] rdf:type car:AverageSpeedEvent "
|
|
+ " ; car:relatedCar ?car "
|
|
+ " ; car:averageSpeed ?avgSpeed . "
|
|
+ "} "
|
|
+ "FROM STREAM <"+RentACarSimulation.CAR_STREAM_IRI+"> [RANGE 5s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " { "
|
|
+ " SELECT ?car (AVG(?speed) AS ?avgSpeed) "
|
|
+ " WHERE { "
|
|
+ " ?e rdf:type car:CarStatusEvent . "
|
|
+ " ?e car:relatedCar ?car . "
|
|
+ " ?e car:speed ?speed . "
|
|
+ " } "
|
|
+ " GROUP BY (?car) "
|
|
+ " }"
|
|
+ "} ";
|
|
QueryContainer queryContainer = new QueryContainer("getAverageSpeedByCar", query, true);
|
|
RentACarSimulation.setUpReasoningOnQueryContainer(queryContainer);
|
|
return queryContainer;
|
|
}
|
|
|
|
/**
|
|
* IMPORTANT NOTE: STREAM gets matched everywhere, so don't call stuff "stream"!
|
|
*/
|
|
public QueryContainer selectFromRegisteredStream() {
|
|
String query = "REGISTER Query askRegisteredStrm AS "
|
|
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
|
|
+ "PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#> "
|
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
|
|
+ "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> "
|
|
+ "SELECT ?s ?p ?o "
|
|
+ "FROM STREAM <http://example.org/stream/getAverageSpeedByCar> [RANGE 5s STEP 1s] "
|
|
+ "WHERE { "
|
|
+ " ?s ?p ?o . "
|
|
+ "} ";
|
|
QueryContainer queryContainer = new QueryContainer("askRegisteredStrm", query, false);
|
|
queryContainer.useObserverWindow();
|
|
return queryContainer;
|
|
}
|
|
}
|