Datenbanken mit Prolog

Aus Informatik
Version vom 26. Februar 2008, 11:51 Uhr von Klaus Kister (Diskussion | Beiträge) (Datenbank Download)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Darstellung anhand der Osterhasendatenbank

ER-Modell

Osterhase.png

Relationen-Modell

Aus dem ERM folgt die nachstehende Relationentabelle: (Primärschlüssel sind unterstrichen, Fremdschlüssel kursiv dargestellt)

Kind(KNr,Name,Alter,Adresse)
Wunsch(WNr,Wunsch,KNr,ONr)
Osterhase(ONr,Name)
Lagerort(LNr,Ort,ONr)
beauftragen(HONr,ONr)
Hilfsosterhase(HONr,Name)
Telefon(TNr,HONr)
entnehmen(LNr,HONr)

Umsetzung in Prolog

%kind(KNr,Name,Alter,Adresse(Straße,Hausnr,Stadt)).
 kind(1,alexander,8,adresse('Nirgendwostr.',37,'Fulda')).
 [...]

Beachte: Großgeschriebenes wird durch Hochkommata gekennzeichnet, da es ansonsten als Variable und nicht als Konstante aufgefasst wird.

Außerdem wurde zur besseren Übersichtlichkeit beim Prädikat Adresse eine Schachtelung vorgenommen, sodass in Adresse die Elemente Straße, Hausnummer und Wohnort enthalten sind.

%osterhase(ONr,Name(Vorname,Nachname)).
 osterhase(1,name('Ingo','Höpping')).
%lagerort(LNr,Ort,ONr).
 lagerort(1,'EDV1',1).
[...]
%hilfsosterhase(HONr,Name).
 hilfsosterhase(1,verena).
[...]
%beauftragen(ONr,HONr).
 beauftragen(1,1).
[...]
%entnehmen(LNr,HONr).
 entnehmen(3,1).
[...]
%wunsch(WNr,Wunsch,KNr,ONr).
 wunsch(1,'Barbie',2,1).
[...]
%telefon(TNr,HONr)
telefon(066584327,1)

Anmerkung: Die komplette Wissensbasis findet sich zum Download am Ende der Seite.

Projektion

Die Projektion Pi1.gifAttribut(Relation) zeigt einzelne Spalten (Attribute) einer Tabelle gemäß der Relationenalgebra. Zur Projektion in Prolog wird hierbei die anonyme Variable _ verwendet, um Spalten auszublenden.

Hier bei der Osterhasendatenbank: Wo wohnen die Kinder?

Anfrage an Wissensbasis:

?- kind(_,Name,_,adresse(_,_,Ort)).

Ausgabe:

Name = alexander
Ort = 'Fulda' ;

Name = lukas
Ort = 'Fulda' ;

Name = florian
Ort = 'Fulda' ;

Name = niklas
Ort = 'KiKa' ;

Name = marcus
Ort = 'Fulda' ;

Name = harry
Ort = 'Wolfsburg' ;

Name = torben
Ort = 'Fulda' ;

Selektion

Die Selektion Sigma.gifFormel(Relation) gibt gemäß der Relationenalgebra Zeilen (Tupel) gemäß der Formel aus. Zur Selektion in Prolog wird eine Variable (erster Buchstabe: Großbuchstabe) verwendet. Beispiel: (hier zur besseren Übersichtlichkeit in Verbindung mit Projektionen) Wie alt ist Torben?

Anfrage:

?- kind(_,torben,Alter,_).

Ausgabe:

Alter = 30

Join (Verknüpfung von Tabellen)

Der Join R Join.gif S verknüpft zwei Tabellen über einem gemeinsamen Attribut. In Prolog wird hierzu eine Anfrage gestellt, in der mehrere Relationen über eine gemeinsame Variable zusammengeführt werden. Beispiel: Was wünscht sich Alexander?

Anfrage:

?- wunsch(_,Wunsch,Kindnummer,_), kind(Kindnummer,alexander,_,_).

Ausgabe:

Wunsch = 'Wunschlos glücklich'
Kindnummer = 1

Erstellen eines Datensatzes

Beispiel für kunde(Knr, Status, Vorname, Nachname, Straße, Plz, Ort, Letzte_werbung, Zahlungsart):

kunde(100,‘S‘,‘Hans‘,‘Voss‘,‘Kuhdamm 12‘,23864,‘Nienwohld‘,‘2005-12-01‘,‘N‘).

Man beachte: Großgeschriebenes wird durch Hochkommas gekennzeichnet, da es ansonsten als Variable und nicht als Konstante aufgefasst wird.

Schachtelung von Prädikaten

Um eine bessere Struktur zu erhalten, werden z.B. die Prädikate name(Vorname, Nachname) und adresse(Straße, Nr., Plz, Ort) in das Prädikat kunde geschachtelt, so dass kunde dann so aussieht:

kunde(Knr,Status,name(Vorname,Nachname),adresse(Straße,Nr,Plz,Ort),Letzte_werbung,Zahlungsart).

Konkrete Fakten der Datenbasis würden dann folgendermaßen aussehen:

kunde(100,‘S‘,name(‘Hans‘,‘Voss‘),adresse(‘Kuhdamm‘,12,23864,‘Nienwohld‘),‘2005-12-01‘,‘N‘).

Projektion

Ein Unterstrich ‘_‘ ist eine sogenannte anonyme Variable, die bei Anfragen nicht mit Variablen gematcht wird.

Interessiert man sich z.B. nur für den Namen und den jeweiligen Wohnort eines Kunden, so wird in der Anfrage bei allem anderen '_' geschrieben:

?- kunde(_, _, Name, adresse(_, _, _, Wohnort), _, _).

Selektion

Sucht man einen Datensatz mit bestimmten Daten, wie z.B. Kunden aus Kayhude, dann werden die Daten in die Anfragen als Konstanten hineingeschrieben. Vorher genanntes Beispiel:

?- kunde(_, _, Name, adresse(_, _, _, 'Kayhude'), _, _).

Verknüpfen von Tabellen

Die Tabellen werden über beliebige Attribute gejoint, wobei die "verknüpfenden" Variablen in den verschiedenen Tabellen identisch geschrieben werden müssen.

So können z.B. alle Konten gesucht werden, bei denen der Kunde nicht gleichzeitig auch der Inhaber ist.

?- kunde(Knr, _, Name, _, _, _),
   girokonto(Knr, Inhaber, _, KontoNr),
   Name \== Inhaber.

Zusätzliche Regeln

Ist man permanent nur an bestimmten, sich oft ändernden Informationen interessiert, dann kann man eine neue Regel schreiben, welche die gewünschten Daten ausgeben kann. (Vergleichbar mit einem View in SQL)

kaufpreis(Bezeichnung,Preis):- 
 artikel(_, Mwst, Bezeichnung, Listenpreis, _,  _, _, _),
 mwstsatz(Mwst, Prozent, _),
 Preis is Listenpreis *(1+Prozent).

kaufpreis gibt also den Preis zzgl. Mehrwertsteuern jedes Artikels aus, ohne andere Daten anzuzeigen.

Diese neue Regel kann man wiederum in anderen Regeln verwenden.

bezahlbar(Bezeichnung,Betrag):- 
 kaufpreis(Bezeichnung,Preis),
 Preis < Betrag.

Aggregatfunktionen

Zunächst muss man hierfür das Systemprädikat findall kennen:

findall(X, Anfrage, Ergebnisliste).

Findall sammelt alle Substitutionen von X in der Anfrage in einer Ergebnisliste.

Die Werte der Ergebnisliste können nun mit Hilfe der arithmetischen Listenoperationen ausgewertet werden, um die Summe, den Durchschnitt, das Minimum / Maximum, die Anzahl usw. der X-Werte herauszubekommen.

Anzahl:

count(X,Befehl, Ergebnis):-
    findall(X,Befehl,L), anzahl(L,Ergebnis). 

Beispiel: Die Anzahl der Kunden

?- count(X, kunde(X,_,_,_,_,_),Anzahl).

Minimum/ Maximum:

minimum(X,Befehl, Ergebnis):-
    findall(X,Befehl,L), mini(L,Ergebnis).
maximum (X,Befehl, Ergebnis):-
    findall(X,Befehl,L), maxi(L,Ergebnis).

Beispiel: Der teuerste/billigste Artikel

?- maximum(X, artikel(_,_,_,X,_,_,_,_), Ergebnis), artikel(_,_,Bezeichnung,Ergebnis,_,_,_,_).
?- minimum(X, artikel(_,_,_,X,_,_,_,_), Ergebnis), artikel(_,_,Bezeichnung,Ergebnis,_,_,_,_).

Summe:

sum(X,Befehl, Ergebnis):-
    findall(X,Befehl,L), summe(L,Ergebnis).

Beispiel: Bestellmenge jedes Artikels

?- artikel(Artikel,_,Bezeichnung,_,_,_,_,_),sum(Bestellmenge, position(_,Artikel,Bestellmenge,_,_),Ergebnis).

Durchschnitt:

avg(X,Befehl, Ergebnis):-
    findall(X,Befehl,L), durchschnitt(L,Ergebnis).

Beispiel: Wie viel Whisky wurde durchschnittlich bestellt?

avg_bestellmenge(Bezeichnung,Ergebnis):-
artikel(Artikel,_,Bezeichnung,_,_,_,_,_), avg(Bestellmenge,position(_,Artikel,Bestellmenge,_,_), Ergebnis). ?- avg_bestellmenge(’Whisky’, Y).

Downloads

Datei:Osterhasen.zip