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 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(); 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 quads = d.getQuadruples(); for(RdfQuadruple q : quads) { this.driverStream.put(q); } } for(Car c : this.carPool.getCars()) { List 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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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 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: " + "PREFIX f: " + "PREFIX xsd: " + "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 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: " + "PREFIX rdfs: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "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: " + "PREFIX f: " + "PREFIX xsd: " + "PREFIX car: <"+RentACarSimulation.BASE_ONTOLOGY_IRI+"> " + "SELECT ?s ?p ?o " + "FROM STREAM [RANGE 5s STEP 1s] " + "WHERE { " + " ?s ?p ?o . " + "} "; QueryContainer queryContainer = new QueryContainer("askRegisteredStrm", query, false); queryContainer.useObserverWindow(); return queryContainer; } }