[TASK] Restructure according to meeting.
This commit is contained in:
parent
c41be84aaa
commit
a02eef5102
|
@ -175,35 +175,6 @@ An einem Beispielszenario soll dann der Praxiseinsatz von C-SPARQL erklärt werd
|
|||
\todo{Ausformulieren}
|
||||
|
||||
|
||||
\section{Einführung in Complex Event Processing}
|
||||
|
||||
\begin{itemize}
|
||||
\item Definition von CEP
|
||||
\item Ereignisse und Hintergrundwissen/Domänenwissen
|
||||
\item Beispielhafter, fiktiver Ereignisstrom mit Hinweis auf Zeitachse
|
||||
\item Kurzer Exkurs in Richtung Mustererkennung
|
||||
\end{itemize}
|
||||
|
||||
Im folgenden Abschnitt wird ein kurzer Einstieg in das Konzept von Complex Event Processing (CEP) gegeben. Eine detailreiche Erläuterung von CEP und die beispielhafte Anwendung der CEP-Engine \enquote{Esper} wird in \cite{hsh:cep} beschrieben.
|
||||
|
||||
Wie der Begriff \enquote{Complex Event Processing} schon andeutet, geht es bei CEP um die Verarbeitung von komplexen Ereignissen --- konkret: Die Erkennung und Erfassung von komplexen Ereignissen aus Datenströmen von primitiven Ereignissen. Von Messereignissen aus mit Sensoren ausgestatteten Geräten über Transaktionen im Handel bis hin zu Benutzerinteraktionen auf Webseiten entstehen täglich unzählig viele, primitive Ereignisse, die abhängig von ihrem Kontext für einen bestimmten Zeitraum ein Stück der echten Welt korrekt abbilden.
|
||||
|
||||
Die in diesen primitiven Ereignissen enthaltenen Informationen stellen nur einen momentanen Zustand dar; sie haben für sich alleine betrachtet keinen Kontext und somit vorerst bedeutungslos. Betrachtet man beispielsweise ein Ereignis \enquote{Die gemessene Temperatur beträgt 42°C.}, so ist zunächst nicht zu erkennen, was es mit dieser Temperatur auf sich hat. Hier kommt das für die Verarbeitung bereits bekannte \emph{Hintergrundwissen} (auch Domänenwissen) ins Spiel, welches das Ereignis in einen bekannten Kontext stellen kann. Es kann uns beispielsweise verraten, dass die Ereignisquelle ein Temperatursensor ist, der sich in einem PKW auf dem Motorblock befindet. Das Hintergrundwissen kann zu der bekannten Umgebung des Sensors viele weitere Angaben enthalten: Das konkrete Fabrikat des PKW, dessen Höchstgeschwindigkeit und die maximal zulässige Betriebstemperatur des Motors. Dieses Wissen ermöglicht schon eine genaue Einordnung der Informationen des Ereignisses; allerdings werden doch noch weitere Informationen benötigt, um ein eindeutiges Bild der Gesamtsituation zu erhalten. Kombiniert man das Temperaturereignis mit den Meldungen des im PKW installierten Geschwindigkeitssensors, so ergibt sich die Möglichkeit herauszufinden, ob für den aktuellen Betriebszustand des PKW die gemessene Motortemperatur.
|
||||
|
||||
Ein weiterer, wichtiger Faktor ist der Zeitraum in dem bestimmte Ereignisse auftreten. Um dies näher zu erläutern, betrachten wir den gegebenen Ereignisstrom aus Listing~\ref{lst:sample_eventstream}.
|
||||
\begin{lstlisting}[caption={Exemplarischer Ereignisstrom: Motortemperatur eines PKW},label={lst:sample_eventstream}]
|
||||
[Event #1] Temperatur: 40°C
|
||||
[Event #2] Temperatur: 48°C
|
||||
[Event #3] Temperatur: 61°C
|
||||
[Event #4] Temperatur: 84°C
|
||||
\end{lstlisting}
|
||||
Auf den ersten Blick ist ersichtlich, dass die Messwerte einen sehr starken Temperaturanstieg abbilden, jedoch fehlt eine Angabe darüber, wie viel Zeit zwischen diesen Ereignissen vergangen ist. Dadurch ist die Interpretation dieser Ereignisse nicht mehr eindeutig möglich: Liegen zwischen den Messereignissen beispielsweise etwa 30-60 Minuten, so könnte es sich um einen normalen Betrieb bei hoher Geschwindigkeit handeln. Sollten jedoch nur wenige Minuten zwischen den Messereignissen vergangen sein, so lassen die Messwerte auf einen Defekt schließen und ein Motorschaden wäre eine mögliche Folge. Die Zeitachse darf somit bei der Ereignisverarbeitung nicht vernachlässigt werden.
|
||||
|
||||
Ein weiterer Kernaspekt von CEP ist die Mustererkennung in Ereignissen. Aus bestimmten primitiven Ereignissen, die in einer bestimmten Abfolge auftreten, soll ein konkreter Sachverhalt abgeleitet werden. Treten bei einem PKW beispielsweise in kurzer Zeit nacheinander die Ereignisse \enquote{Motor abgeschaltet}, \enquote{Fahrzeug verriegelt} und \enquote{PKW beschleunigt} auf, so könnte der Fall eingetreten sein, dass ein gerade abgestelltes Fahrzeug losgerollt ist und es sollte unverzüglich eine Reaktion darauf gestartet werden.
|
||||
|
||||
Insgesamt liegt die Herausforderung von CEP darin, in kürzester Zeit große Datenströme von Ereignissen mit Hintergrundwissen anzureichern, diese zu höherwertigen Ereignissen zu kombinieren und bestimmte Muster zu finden, sowie die Ergebnisse mit möglichst geringer Verzögerung in Echtzeit ausgeben zu können oder Reaktionen einzuleiten.
|
||||
|
||||
|
||||
\chapter{RDF und das semantische Web}
|
||||
|
||||
\begin{itemize}
|
||||
|
@ -304,63 +275,34 @@ Da Ontologien auch genutzt werden können, um Wissen aus den Strukturen einer On
|
|||
Diesen Vorteil erkauft man sich durch einen nicht unerheblichen Einsatz von Rechenleistung, da im Prozess des Reasoning eine Menge von zusätzlichen Daten entsteht, für die zusätzlich zu den bereits vorhandenen Daten die Regeln aller genutzten Ontologien berücksichtigt werden müssen. Behandelt man lediglich statische Daten, die sich kaum bis garnicht ändern, so ist der nötige Aufwand für Reasoning übersichtlich und liegt auch für große Mengen von Daten und Ontologien in einem akzeptablem Rahmen. Ändern sich jedoch häufig Daten, so muss für das Subset der sich geänderten Daten der Reasoning-Prozess erneut durchgeführt werden um eine vollständig aktuelle Datenbasis zu erhalten.
|
||||
|
||||
|
||||
\chapter{CEP auf RDF-Datenströmen}
|
||||
|
||||
|
||||
\section{Ereignisse als RDF-Datenstrom}
|
||||
|
||||
Um Ereignisse aus verschiedenen Quellen gemeinsam zu verarbeiten ist RDF als kleinster gemeinsamer Nenner für Informationen das Mittel der Wahl. Hierbei werden die Ereignisse gegebenenfalls vorher in das RDF-Format transformiert und als Datenstrom aus RDF-Quadrupeln der CEP-Engine zugeführt. Die Quadrupel führen neben den ereignisrelevanten Informationen zusätzlich noch den Zeitstempel mit, zu dem das Ereignis ausgelöst wurde.
|
||||
Als Abfragesprache für die RDF-Datenströme kommt eine erweiterte Form von SPARQL --- im Folgenden \enquote{CSPARQL} --- zum Einsatz, welche Erweiterungen und Funktionen speziell für die Verarbeitung von RDF-Datenströmen mitbringt. CSPARQL kann die eingehenden RDF-Datenströme in sogenannten \enquote{Sliding Windows} erfassen und ermöglicht die Berücksichtigung der Zeitstempel der Ereignisse innerhalb der Abfrage durch die Bereitstellung von zusätzlichen Sprachkonstrukten und Funktionen. Dabei besteht weiterhin die Möglichkeit, lokal in Form von RDF-Daten vorhandenes Domänenwissen in die Abfrage einzubeziehen und mit den Ereignisdaten zu verknüpfen.
|
||||
|
||||
In Listing~\ref{lst:sample_rdf_event} aufgeführt sind RDF-Tripel, die ein beispielhaftes Zustands-Ereignis aus einem PKW zeigen.
|
||||
\begin{lstlisting}[caption={Ereignis im RDF-Format},label={lst:sample_rdf_event}]
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#carID http://myexample.org/cars#8
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentTemperature "27"^^http://www.w3.org/2001/XMLSchema#integer
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentSpeed "13"^^http://www.w3.org/2001/XMLSchema#integer
|
||||
\end{lstlisting}
|
||||
|
||||
\todo{Noch ein wenig auf das Listing eingehen, URIs und die fiktiven Prädikate etwas erläutern}
|
||||
|
||||
|
||||
\section{SPARQL-Erweiterung zur Verarbeitung von RDF-Datenströmen}
|
||||
|
||||
Der große Vorteil bei der Ereignisverarbeitung mit SPARQL auf RDF-Daten liegt in der Mächtigkeit dieser Abfragesprache: Innerhalb einer einzigen SPARQL-Abfrage ist es möglich Ereignisse aus verschiedenen Quellen miteinander zu kombinieren, direkt mit Hintergrundwissen zu kombinieren, nach eigenen Kriterien zu filtern, einfache Berechnungen anzustellen und aus dem Ergebnis neue Ereignisse beliebiger Struktur zu erzeugen.
|
||||
Somit muss der Anwender neben SPARQL keine weiteren Sprachen lernen oder sich anderweitig mit der Implementierung der Engine auseinandersetzen, sondern kann sich komplett auf die zu analysierenden Ereignisse konzentrieren. Listing~\ref{lst:sample_combine_events_sparql} zeigt einen SPARQL-Query, in dem zwei aufeinanderfolgende Ereignisse mit Angaben zur Momentangeschwindigkeit eines Autos zu einem komplexeren Beschleunigungsereignis kombiniert werden.
|
||||
|
||||
\begin{lstlisting}[caption={Kombination von Ereignissen mit SPARQL},label={lst:sample_combine_events_sparql}]
|
||||
REGISTER QUERY ConstructAcceleratingCars AS
|
||||
PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#>
|
||||
PREFIX cars: <http://myexample.org/cars#>
|
||||
CONSTRUCT {
|
||||
[] cars:carID ?car;
|
||||
cars:acceleratedBy ?deltaSpeed .
|
||||
}
|
||||
FROM STREAM <http://myexample.org/cars> [RANGE 5s STEP 1s]
|
||||
WHERE {
|
||||
?e1 cars:carID ?car ;
|
||||
cars:currentSpeed ?speed1 .
|
||||
?e2 cars:carID ?car ;
|
||||
cars:currentSpeed ?speed2 .
|
||||
BIND (?speed2 - ?speed1 AS ?deltaSpeed)
|
||||
FILTER(f:timestamp(?e1,cars:carID,?car) < f:timestamp(?e2,cars:carID,?car))
|
||||
FILTER(?speed1 < ?speed2)
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\todo{Streaming-Erweiterungen aus dem Listiung ein wenig hervorheben}
|
||||
|
||||
|
||||
\section{Resoning auf RDF-Datenströmen?}
|
||||
\chapter{Einführung in Complex Event Processing}
|
||||
|
||||
\begin{itemize}
|
||||
\item Immer noch ein Forschungsgebiet
|
||||
\item sehr hoher Datendurchsatz (viele kleine Ereignisse in geringem Zeitraum)
|
||||
\item Ereignisinformationen ändern sich sehr häufig, sind nie sehr lange gültig und nicht immer relevant zur einer Abfrage
|
||||
\item Aber: Ergebnisse sollen möglichst schnell vorliegen
|
||||
\item $\Longrightarrow$ große Menge Rechenaufwand
|
||||
\item Einer der möglichen Ansätze: Reasoner errechnet für die Ereignisse Tripel mit begrenzter Lebensdauer
|
||||
\item Definition von CEP
|
||||
\item Ereignisse und Hintergrundwissen/Domänenwissen
|
||||
\item Beispielhafter, fiktiver Ereignisstrom mit Hinweis auf Zeitachse
|
||||
\item Kurzer Exkurs in Richtung Mustererkennung
|
||||
\end{itemize}
|
||||
|
||||
Im folgenden Abschnitt wird ein kurzer Einstieg in das Konzept von Complex Event Processing (CEP) gegeben. Eine detailreiche Erläuterung von CEP und die beispielhafte Anwendung der CEP-Engine \enquote{Esper} wird in \cite{hsh:cep} beschrieben.
|
||||
|
||||
Wie der Begriff \enquote{Complex Event Processing} schon andeutet, geht es bei CEP um die Verarbeitung von komplexen Ereignissen --- konkret: Die Erkennung und Erfassung von komplexen Ereignissen aus Datenströmen von primitiven Ereignissen. Von Messereignissen aus mit Sensoren ausgestatteten Geräten über Transaktionen im Handel bis hin zu Benutzerinteraktionen auf Webseiten entstehen täglich unzählig viele, primitive Ereignisse, die abhängig von ihrem Kontext für einen bestimmten Zeitraum ein Stück der echten Welt korrekt abbilden.
|
||||
|
||||
Die in diesen primitiven Ereignissen enthaltenen Informationen stellen nur einen momentanen Zustand dar; sie haben für sich alleine betrachtet keinen Kontext und somit vorerst bedeutungslos. Betrachtet man beispielsweise ein Ereignis \enquote{Die gemessene Temperatur beträgt 42°C.}, so ist zunächst nicht zu erkennen, was es mit dieser Temperatur auf sich hat. Hier kommt das für die Verarbeitung bereits bekannte \emph{Hintergrundwissen} (auch Domänenwissen) ins Spiel, welches das Ereignis in einen bekannten Kontext stellen kann. Es kann uns beispielsweise verraten, dass die Ereignisquelle ein Temperatursensor ist, der sich in einem PKW auf dem Motorblock befindet. Das Hintergrundwissen kann zu der bekannten Umgebung des Sensors viele weitere Angaben enthalten: Das konkrete Fabrikat des PKW, dessen Höchstgeschwindigkeit und die maximal zulässige Betriebstemperatur des Motors. Dieses Wissen ermöglicht schon eine genaue Einordnung der Informationen des Ereignisses; allerdings werden doch noch weitere Informationen benötigt, um ein eindeutiges Bild der Gesamtsituation zu erhalten. Kombiniert man das Temperaturereignis mit den Meldungen des im PKW installierten Geschwindigkeitssensors, so ergibt sich die Möglichkeit herauszufinden, ob für den aktuellen Betriebszustand des PKW die gemessene Motortemperatur.
|
||||
|
||||
Ein weiterer, wichtiger Faktor ist der Zeitraum in dem bestimmte Ereignisse auftreten. Um dies näher zu erläutern, betrachten wir den gegebenen Ereignisstrom aus Listing~\ref{lst:sample_eventstream}.
|
||||
\begin{lstlisting}[caption={Exemplarischer Ereignisstrom: Motortemperatur eines PKW},label={lst:sample_eventstream}]
|
||||
[Event #1] Temperatur: 40°C
|
||||
[Event #2] Temperatur: 48°C
|
||||
[Event #3] Temperatur: 61°C
|
||||
[Event #4] Temperatur: 84°C
|
||||
\end{lstlisting}
|
||||
Auf den ersten Blick ist ersichtlich, dass die Messwerte einen sehr starken Temperaturanstieg abbilden, jedoch fehlt eine Angabe darüber, wie viel Zeit zwischen diesen Ereignissen vergangen ist. Dadurch ist die Interpretation dieser Ereignisse nicht mehr eindeutig möglich: Liegen zwischen den Messereignissen beispielsweise etwa 30-60 Minuten, so könnte es sich um einen normalen Betrieb bei hoher Geschwindigkeit handeln. Sollten jedoch nur wenige Minuten zwischen den Messereignissen vergangen sein, so lassen die Messwerte auf einen Defekt schließen und ein Motorschaden wäre eine mögliche Folge. Die Zeitachse darf somit bei der Ereignisverarbeitung nicht vernachlässigt werden.
|
||||
|
||||
Ein weiterer Kernaspekt von CEP ist die Mustererkennung in Ereignissen. Aus bestimmten primitiven Ereignissen, die in einer bestimmten Abfolge auftreten, soll ein konkreter Sachverhalt abgeleitet werden. Treten bei einem PKW beispielsweise in kurzer Zeit nacheinander die Ereignisse \enquote{Motor abgeschaltet}, \enquote{Fahrzeug verriegelt} und \enquote{PKW beschleunigt} auf, so könnte der Fall eingetreten sein, dass ein gerade abgestelltes Fahrzeug losgerollt ist und es sollte unverzüglich eine Reaktion darauf gestartet werden.
|
||||
|
||||
Insgesamt liegt die Herausforderung von CEP darin, in kürzester Zeit große Datenströme von Ereignissen mit Hintergrundwissen anzureichern, diese zu höherwertigen Ereignissen zu kombinieren und bestimmte Muster zu finden, sowie die Ergebnisse mit möglichst geringer Verzögerung in Echtzeit ausgeben zu können oder Reaktionen einzuleiten.
|
||||
|
||||
|
||||
\chapter{Gegenüberstellung existierender CEP-Engines}
|
||||
|
||||
|
@ -426,17 +368,6 @@ Grobe Eckpunkte zur Orientierung:
|
|||
\end{itemize}
|
||||
|
||||
|
||||
\section{Esper}
|
||||
|
||||
\begin{itemize}
|
||||
\item Quasi auch jetzt aktuell, da kommerzieller Hintergrund
|
||||
\item SQL-ähnliche Sprache
|
||||
\item Events sind durch Java-Objekte mit Attributen repräsentiert $\Longrightarrow$ Schemaartige Strukturen
|
||||
\item Recht populär, stark verbreitet 2010 nach \cite{iao:esper}[Marktübersicht Real-Time Monitoring Software]
|
||||
\item Integration von Hintergrundwissen nicht direkt in der Abfragesprache möglich (afaik!)
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{C-SPARQL}
|
||||
|
||||
\begin{itemize}
|
||||
|
@ -450,8 +381,66 @@ Grobe Eckpunkte zur Orientierung:
|
|||
\item Reasoning zur Zeit nicht enthalten, aber es gibt Papers zu den Themen
|
||||
\end{itemize}
|
||||
|
||||
\chapter{CEP auf RDF-Datenströmen (Konzept)}
|
||||
|
||||
\chapter{Nutzung der Engine C-SPARQL}
|
||||
Hier kommt der Part hin mit der abstrakten CQL für die Situation + C-SPARQL-Queries
|
||||
|
||||
\section{Ereignisse als RDF-Datenstrom}
|
||||
|
||||
Um Ereignisse aus verschiedenen Quellen gemeinsam zu verarbeiten ist RDF als kleinster gemeinsamer Nenner für Informationen das Mittel der Wahl. Hierbei werden die Ereignisse gegebenenfalls vorher in das RDF-Format transformiert und als Datenstrom aus RDF-Quadrupeln der CEP-Engine zugeführt. Die Quadrupel führen neben den ereignisrelevanten Informationen zusätzlich noch den Zeitstempel mit, zu dem das Ereignis ausgelöst wurde.
|
||||
Als Abfragesprache für die RDF-Datenströme kommt eine erweiterte Form von SPARQL --- im Folgenden \enquote{CSPARQL} --- zum Einsatz, welche Erweiterungen und Funktionen speziell für die Verarbeitung von RDF-Datenströmen mitbringt. CSPARQL kann die eingehenden RDF-Datenströme in sogenannten \enquote{Sliding Windows} erfassen und ermöglicht die Berücksichtigung der Zeitstempel der Ereignisse innerhalb der Abfrage durch die Bereitstellung von zusätzlichen Sprachkonstrukten und Funktionen. Dabei besteht weiterhin die Möglichkeit, lokal in Form von RDF-Daten vorhandenes Domänenwissen in die Abfrage einzubeziehen und mit den Ereignisdaten zu verknüpfen.
|
||||
|
||||
In Listing~\ref{lst:sample_rdf_event} aufgeführt sind RDF-Tripel, die ein beispielhaftes Zustands-Ereignis aus einem PKW zeigen.
|
||||
\begin{lstlisting}[caption={Ereignis im RDF-Format},label={lst:sample_rdf_event}]
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#carID http://myexample.org/cars#8
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentTemperature "27"^^http://www.w3.org/2001/XMLSchema#integer
|
||||
http://myexample.org/cars/event#1468064960110 http://myexample.org/cars#currentSpeed "13"^^http://www.w3.org/2001/XMLSchema#integer
|
||||
\end{lstlisting}
|
||||
|
||||
\todo{Noch ein wenig auf das Listing eingehen, URIs und die fiktiven Prädikate etwas erläutern}
|
||||
|
||||
|
||||
\section{SPARQL-Erweiterung zur Verarbeitung von RDF-Datenströmen}
|
||||
|
||||
Der große Vorteil bei der Ereignisverarbeitung mit SPARQL auf RDF-Daten liegt in der Mächtigkeit dieser Abfragesprache: Innerhalb einer einzigen SPARQL-Abfrage ist es möglich Ereignisse aus verschiedenen Quellen miteinander zu kombinieren, direkt mit Hintergrundwissen zu kombinieren, nach eigenen Kriterien zu filtern, einfache Berechnungen anzustellen und aus dem Ergebnis neue Ereignisse beliebiger Struktur zu erzeugen.
|
||||
Somit muss der Anwender neben SPARQL keine weiteren Sprachen lernen oder sich anderweitig mit der Implementierung der Engine auseinandersetzen, sondern kann sich komplett auf die zu analysierenden Ereignisse konzentrieren. Listing~\ref{lst:sample_combine_events_sparql} zeigt einen SPARQL-Query, in dem zwei aufeinanderfolgende Ereignisse mit Angaben zur Momentangeschwindigkeit eines Autos zu einem komplexeren Beschleunigungsereignis kombiniert werden.
|
||||
|
||||
\begin{lstlisting}[caption={Kombination von Ereignissen mit SPARQL},label={lst:sample_combine_events_sparql}]
|
||||
REGISTER QUERY ConstructAcceleratingCars AS
|
||||
PREFIX f: <http://larkc.eu/csparql/sparql/jena/ext#>
|
||||
PREFIX cars: <http://myexample.org/cars#>
|
||||
CONSTRUCT {
|
||||
[] cars:carID ?car;
|
||||
cars:acceleratedBy ?deltaSpeed .
|
||||
}
|
||||
FROM STREAM <http://myexample.org/cars> [RANGE 5s STEP 1s]
|
||||
WHERE {
|
||||
?e1 cars:carID ?car ;
|
||||
cars:currentSpeed ?speed1 .
|
||||
?e2 cars:carID ?car ;
|
||||
cars:currentSpeed ?speed2 .
|
||||
BIND (?speed2 - ?speed1 AS ?deltaSpeed)
|
||||
FILTER(f:timestamp(?e1,cars:carID,?car) < f:timestamp(?e2,cars:carID,?car))
|
||||
FILTER(?speed1 < ?speed2)
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\todo{Streaming-Erweiterungen aus dem Listiung ein wenig hervorheben}
|
||||
|
||||
|
||||
\section{Resoning auf RDF-Datenströmen?}
|
||||
|
||||
\begin{itemize}
|
||||
\item Immer noch ein Forschungsgebiet
|
||||
\item sehr hoher Datendurchsatz (viele kleine Ereignisse in geringem Zeitraum)
|
||||
\item Ereignisinformationen ändern sich sehr häufig, sind nie sehr lange gültig und nicht immer relevant zur einer Abfrage
|
||||
\item Aber: Ergebnisse sollen möglichst schnell vorliegen
|
||||
\item $\Longrightarrow$ große Menge Rechenaufwand
|
||||
\item Einer der möglichen Ansätze: Reasoner errechnet für die Ereignisse Tripel mit begrenzter Lebensdauer
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\chapter{Nutzung der Engine C-SPARQL (Implementation)}
|
||||
|
||||
In diesem Kapitel wird die C-SPARQL-Engine konkret vorgestellt und verwendet.
|
||||
\begin{itemize}
|
||||
|
|
Loading…
Reference in New Issue