home *** CD-ROM | disk | FTP | other *** search
- /********************************************************/
- /* SQL.PRO */
- /* Selektieren und Sortieren von Datensätzen */
- /* Mit einer SQL-ähnlichen Abfrage-Sprache */
- /* (C) 1989,1990 O.P.Prem & TOOLBOX */
-
- code=3500
- trail=100
-
- DOMAINS
- file = f
- t = t(string,string)
- infolist = reference sortinfo*
- /* z.B. [h("+",1),h("-",2)]
- = es wird nach dem ersten Feld aufsteigend
- und nach dem zweiten Feld absteigend sortiert */
- sortinfo = reference h(string,integer)
- strulist = t*
- /* z.B. [t("ZUNAME","s"),t("VORNAME","s"),t("ALTER","i")]
- = die Datei besteht aus zwei Datenfeldern vom
- Typ 'string' und einem vom Typ 'integer' */
- element = i(integer); s(string); r(real)
- list = string*
- slist = element*
- exp = reference g(integer,slist);
- und(exp,exp); oder(exp,exp); nicht(exp)
- /* z.B. oder(g(1,[s("IN"),s("A"),s("H")]),g(2,
- [s("="),s("Thomas")]))
- = Zuname in A..H oder Vorname=Thomas (Zuname ist
- das erste Datenfeld und Vorname das zweite) */
- gew = reference daten(slist); selektiert(slist)
- gewlist = reference gew*
- /* notwendig, um das vordefinierte Prädikat
- findall für die Datenbasis verwenden zu können */
-
- DATABASE
- eingabe(list)
- /* enthält die abgearbeitete Liste der eingegebenen
- Selektierkriterien; wenn ein sinnvoller Ausdruck
- eingegeben wurde, ist diese Liste leer. */
- daten(slist) /* Die eingelesenen Datensätze */
- feldnamen(strulist) /* enthält die Dateistruktur */
- name_der_Datei(string) /* enthält den Dateinamen */
- selektiert(slist) /* Die selektierten Datensätze */
- ende(string) /* Bedingung für das Programmende */
- n(integer) /* Zähler für die Ausgabe von Datensätzen
- durch das Prädikat 'out1' */
-
- PREDICATES
- readexp(exp,list).
- member(string,string,integer,integer,strulist).
- tokl(string,list).
- ausgabe_struktur(string).
- ausgabe(strulist,integer)
- umwandeln(list,list,exp).
- konversion(string,string,element).
- ch_exp(list,list,exp). ch_term(list,list,exp)
- ch_term1(list,list,exp,exp).
- art_der_auswahl(infolist,exp).
- vorn(string,list,list)
- erzeugen(list,list,string,slist). run.
- loeschen(dbasedom).
- felder(strulist,integer,integer).
- read_Data(string,integer).
- read_Records(strulist,integer)
- read_One_Record(strulist,integer,integer,slist)
- lesen. suchen(exp). verarbeite(integer). menu
- pruefe_satz(slist,exp). pruefe_relation(element,slist).
- comp_string(element,slist). comp_int(element,slist).
- comp_real(element,slist).
- out1. out(gewlist,integer)
- n_tes(slist,integer,element). zerlegen(list,list,list).
- check(list,infolist).
- qsort(gewlist,gewlist,gewlist,infolist).
- split(slist,gewlist,gewlist,gewlist,infolist)
- dem(infolist,gew,slist). choose(gew,slist)
- ab(gew,slist,element,element,infolist)
- auf(gew,slist,element,element,infolist)
- wahl1(gew). wahl2(gew). mode1(exp). mode2(infolist).
- schreibe(slist,integer). warte(integer)
- sammle(gew,slist,infolist)
-
- CLAUSES
- /* MENÜAUFBAU */
- run:-
- makewindow(1,7,7,
- "Selektieren und Sortieren von Datensätzen",0,0,25,80),
- menu.
- run:- not(ende("ENDE")),run.
- menu:- clearwindow,
- cursor(6,15),write("(1) neue Datei"),
- cursor(8,15),
- write("(2) Auswahl von Datensätzen"),
- cursor(10,15),write("(3) Ende"),
- cursor(13,15),write("Wählen Sie: "),
- readint(Wahl),nl,
- verarbeite(Wahl),!,menu.
-
- /* AUSFÜHRUNG DER MENÜWAHL */
- verarbeite(1):- lesen,!,readexp(Exp,Sort),
- check(Sort,Sort1),
- eingabe([]),art_der_auswahl(Sort1,Exp).
- verarbeite(1):- removewindow,closefile(f),
- readdevice(keyboard),fail.
- verarbeite(2):- name_der_Datei(_),!,
- loeschen(selektiert(_)),
- loeschen(n(_)),
- readexp(Exp,Sort),check(Sort,Sort1),
- eingabe([]),art_der_auswahl(Sort1,Exp).
- verarbeite(2):- verarbeite(1).
- verarbeite(3):- !,asserta(ende("ENDE")),fail.
- verarbeite(_).
-
- /* ART DER SELEKTION UND SORTIERUNG */
- art_der_auswahl(S,E):- not(mode1(E)),not(mode2(S)),
- suchen(E), findall(X,wahl1(X),Ungeordnet),
- qsort(Ungeordnet,Geordnet,_,S),
- clearwindow,out(Geordnet,1),readchar(_).
- /* Selektieren und Sortieren */
- art_der_auswahl(S,E):- not(mode1(E)),mode2(S),suchen(E),
- findall(X,wahl1(X),L),clearwindow,
- out(L,1),readchar(_).
- /* Selektieren, kein Sortieren */
- art_der_auswahl(S,E):- mode1(E),not(mode2(S)),
- findall(X,wahl2(X),Ungeordnet),
- qsort(Ungeordnet,Geordnet,_,S),
- clearwindow,out(Geordnet,1),readchar(_).
- /* alle Datensätze sortiert */
- art_der_auswahl(S,E):- mode1(E),mode2(S),asserta(n(1)),
- clearwindow,out1,readchar(_).
- /* alle Datensätze unsortiert */
-
- /* EINGABE DER SELEKTIER- UND SORTIERKRITERIEN */
- readexp(Exp,Sort):- clearwindow,name_der_Datei(S),
- ausgabe_struktur(S),nl,nl,
- write(" Selektier- und Sortierkriterien:"),nl,
- write(" "),readln(Str),tokl(Str,Tok),
- zerlegen(Tok,Selekt,Sort),umwandeln(Selekt,L,Exp),
- asserta(eingabe(L)),!.
- readexp(_,_):- nl,nl,write("falscher Ausdruck"),
- readchar(_),fail.
-
- /* Umwandeln einer Zeichenkette in eine Tokenliste */
- tokl(STR,[H|T]):- fronttoken(Str,H,Str1),!,tokl(Str1,T).
- tokl(_,[]).
-
- /* UMWANDELN DER EINGEGEBENEN SELEKTIERKRITERIEN
- IN EINEN AUSDRUCK IN PRÄFIXNOTATION
- (siehe das Beispiel zum domain 'exp') */
-
- umwandeln([],[],g(0,[])):- !.
- /* Ausgabe aller Datensätze */
- umwandeln(S,L,Exp):- ch_exp(S,L,Exp).
-
- ch_exp(In,Out,Exp):- ch_term(In,Out1,Exp1),
- ch_term1(Out1,Out,Exp1,Exp).
-
- ch_term([X|IL],Ol,nicht(Exp)):-
- upper_lower("NICHT",X),!,ch_exp(IL,Ol,Exp).
- ch_term(["("|IL],Ol,Exp):- !,ch_exp(IL,Ol1,Exp),
- vorn(")",Ol1,Ol),!.
- ch_term([H|IL],Ol,g(Nr,Bed)):-
- feldnamen(Flist),member(H,Art,Nr,1,Flist),
- erzeugen(IL,Ol,Art,Bed).
-
- ch_term1([X|IL],Ol,Exp1,Exp):-
- upper_lower("UND",X),!,ch_term(IL,Ol1,Exp2),
- ch_term1(Ol1,Ol,und(Exp1,Exp2),Exp).
- ch_term1([X|IL],Ol,Exp1,Exp):-
- upper_lower("ODER",X),ch_term(IL,Ol1,Exp2),
- ch_term1(Ol1,Ol,oder(Exp1,Exp2),Exp).
- ch_term1(IL,IL,Exp,Exp):- !.
-
- /* Darstellung eines bestimmten Auswahlkriteriums
- in Listenform z.B.
- <=20 in Form von [s("<="),i(20)] */
- erzeugen([Op,X,C,C,Y|T],T,Art,[s("IN"),X1,Y1]):-
- upper_lower("IN",Op),
- str_char(C,'.'),!,
- konversion(Art,X,X1),konversion(Art,Y,Y1).
- erzeugen(["<","=",X|T],T,Art,[s("<="),Y]):-
- !,konversion(Art,X,Y).
- erzeugen([">","=",X|T],T,Art,[s(">="),Y]):-
- !,konversion(Art,X,Y).
- erzeugen(["<",X|T],T,Art,[s("<"),Y]):-
- !,konversion(Art,X,Y).
- erzeugen([">",X|T],T,Art,[s(">"),Y]):-
- !,konversion(Art,X,Y).
- erzeugen(["=",X|T],T,Art,[s("="),Y]):-
- !,konversion(Art,X,Y).
- erzeugen(["<",">",X|T],T,Art,[s("<>"),Y]):-
- !,konversion(Art,X,Y).
- erzeugen(_,_,_,_):- asserta(eingabe([""])),fail.
-
- /* Abspalten des Listenkopfes und
- Rücklieferung des Restes der Liste */
- vorn(X,[X|T],T).
-
- /* Löschen der gesamten Datenbasis
- oder eines Teils der Datenbasis */
- loeschen(X):- retract(X),fail.
- loeschen(_).
-
- /* ERMITTLUNG DER DATEISTRUKTUR
- UND EINLESEN DER DATENSÄTZE
- Die Dateistruktur ist unter NAME.STR gespeichert;
- die Datei, die die Datensätze enthält,
- muß den Zusatz 'DAT' besitzen; die Datensätze
- werden der Datenbasis hinzugefügt */
-
- lesen:- loeschen(_),
- makewindow(2,7,7,"Datei wählen!",5,20,15,40),
- clearwindow,dir(".","*.dat",Dateiname),
- tokl(Dateiname,[H|_]),concat(H,".str",SDatei),
- write(""),openread(f,SDatei),readdevice(f),
- felder(FeldL,NoF,0),asserta(feldnamen(FeldL)),
- closefile(f),read_Data(Dateiname,NoF),!,
- removewindow,asserta(name_der_Datei(Dateiname)).
-
- /* Lesen der Dateistruktur:
- Lesen der Feldnamen und Feldtypen;
- Ermittlung der Zahl der Datenfelder;
- siehe das Beispiel zum domain 'strulist' */
- felder([t(A,B)|R],Anzahl,N):-
- not(eof(f)),!,readln(A),readln(B),
- N1=N+1,felder(R,Anzahl,N1).
- felder([],N,N).
-
- /* Routinen zum Lesen der Datei und zum
- Transfer der Datensätze in das Prädikat 'daten'
- der Datenbasis */
- read_Data(FileName,FeldProRec):-
- openread(f,FileName),readdevice(f),
- feldnamen(L),read_Records(L,FeldProRec),
- readdevice(keyboard),closefile(f).
-
- read_Records(L,NrFeld):-
- not(eof(f)),!,read_One_Record(L,1,NrFeld,X),
- assertz(daten(X)),read_Records(L,NrFeld).
- read_Records(_,_). /* Lesen der Datei */
-
- read_One_Record(_,N,NrFeld,[]):-
- N>NrFeld. /* Lesen eines Datensatzes */
- read_One_Record([t(_,Typ)|T1],N,NrFeld,[E|T2]):-
- !,readln(Str),konversion(Typ,Str,E),N1=N+1,
- read_One_Record(T1,N1,NrFeld,T2).
-
- /* Umwandeln in den richtigen Datentyp */
- konversion("s",X,s(X)):-!.
- konversion("i",X,i(Y)):- !,str_int(X,Y).
- konversion("r",X,r(Y)):- str_real(X,Y).
-
- /* Feststellung, ob der eingegebene Feldname
- richtig ist; außerdem Ermittlung von
- Feldnummer und Feldart */
- member(Y,Art,Nr,Nr,[t(X,Art)|_]):- upper_lower(X,Y),!.
- member(X,Art,Nr,N,[_|T]):- N1=N+1,member(X,Art,Nr,N1,T).
-
- /* Ausgabe der Dateistruktur */
- ausgabe_struktur(Name):-
- cursor(1,1),
- write("Die Datei ",Name," hat folgende Struktur:"),nl,
- write(" "),feldnamen(Felder),ausgabe(Felder,1).
-
- ausgabe([],_)./* Ausgabe der Feldnamen und ihrer Typen */
- ausgabe([t(A,B)|T],N):-
- N mod 4=0,!,write(A,"(",B,") "),nl,write(" "),
- N1=N+1,ausgabe(T,N1).
- ausgabe([t(A,B)|T],N):-
- write(A,"(",B,") "),N1=N+1,ausgabe(T,N1).
-
- /* AUSWAHL DER DATENSÄTZE die selektierten Datensätze
- werden in der Datenbank unter 'selektiert'
- gespeichert */
- suchen(Exp):- daten(Rec),pruefe_satz(Rec,Exp),
- assertz(selektiert(Rec)),fail.
- suchen(_).
-
- /* werden die Auswahlkriterien erfüllt? */
- pruefe_satz(_,g(0,[])):- !.
- pruefe_satz(Rec,g(Nr,Rel)):- !,n_tes(Rec,Nr,Feld),
- pruefe_relation(Feld,Rel).
- pruefe_satz(Rec,und(Exp1,Exp2)):-
- !,pruefe_satz(Rec,Exp1), pruefe_satz(Rec,Exp2).
- pruefe_satz(Rec,oder(Exp1,_)):-
- pruefe_satz(Rec,Exp1),!.
- pruefe_satz(Rec,oder(_,Exp2)):- pruefe_satz(Rec,Exp2),!.
- pruefe_satz(Rec,nicht(Exp)):- not(pruefe_satz(Rec,Exp)).
-
- /* Überprüfen eines bestimmten Kriteriums */
- pruefe_relation(s(X),Y):- !,comp_string(s(X),Y).
- pruefe_relation(i(X),Y):- !,comp_int(i(X),Y).
- pruefe_relation(r(X),Y):- comp_real(r(X),Y).
-
- /* Stringvergleiche */
- comp_string(s(F),[s("<="),s(X)]):- F<=X.
- comp_string(s(F),[s(">="),s(X)]):- F>=X.
- comp_string(s(F),[s("<"),s(X)]):- F<X.
- comp_string(s(F),[s(">"),s(X)]):- F>X.
- comp_string(s(F),[s("="),s(X)]):- F=X.
- comp_string(s(F),[s("<>"),s(X)]):- F<>X.
- comp_string(s(F),[s("IN"),s(X),s(Y)]):- F>=X,F<=Y.
-
- /* Integervergleiche */
- comp_int(i(F),[s("<="),i(X)]):- F<=X.
- comp_int(i(F),[s(">="),i(X)]):- F>=X.
- comp_int(i(F),[s("<"),i(X)]):- F<X.
- comp_int(i(F),[s(">"),i(X)]):- F>X.
- comp_int(i(F),[s("="),i(X)]):- F=X.
- comp_int(i(F),[s("<>"),i(X)]):- F<>X.
- comp_int(i(F),[s("IN"),i(X),i(Y)]):- F>=X,F<=Y.
-
- /* Realzahlenvergleiche */
- comp_real(r(F),[s("<="),r(X)]):- F<=X.
- comp_real(r(F),[s(">="),r(X)]):- F>=X.
- comp_real(r(F),[s("<"),r(X)]):- F<X.
- comp_real(r(F),[s(">"),r(X)]):- F>X.
- comp_real(r(F),[s("="),r(X)]):- F=X.
- comp_real(r(F),[s("<>"),r(X)]):- F<>X.
- comp_real(r(F),[s("IN"),r(X),r(Y)]):- F>=X,F<=Y.
-
- n_tes([K|_],1,K):-!. /* n-tes Element einer Liste */
- n_tes([_|T],N,E):- N1=N-1,n_tes(T,N1,E).
-
- /* Ausgabe der selektierten und sortierten Datensätze */
- out([],_).
- out([H|T],N):- choose(H,X),schreibe(X,N),nl,
- N1=N+1,out(T,N1).
-
- /* Zerlegen der Tokenliste in eine Selektionskriterien- und in eine
- Sortierkriterienliste */
- zerlegen([H|T],[H|R],S):-
- not(upper_lower("SORTIERT",H)), zerlegen(T,R,S),!.
- zerlegen([],[],[]):-!.
- zerlegen([_|T],[],T).
-
- /* Überprüfung der Sortierkriterien und Umwandlung in
- eine Liste; siehe das Beispiel zum domain 'infolist'*/
- check([],[]):- !.
- check([","|R],T):- check(R,T).
- check(["-",X|R],[h("-",N)|T]):-
- !,feldnamen(F),member(X,_,N,1,F), check(R,T).
- check([X|R],[h("+",N)|T]):-
- feldnamen(F),member(X,_,N,1,F),check(R,T).
-
- /* SORTIERROUTINEN */
- qsort([H|T],S,X,Krit):-
- sammle(H,L,Krit),split(L,T,A,B,Krit),!,
- qsort(A,S,[H|Y],Krit),
- qsort(B,Y,X,Krit).
- qsort([],X,X,_).
-
- split(L,[A|X],[A|Y],Z,Krit):-
- dem(Krit,A,L),!,split(L,X,Y,Z,Krit).
- split(L,[A|X],Y,[A|Z],Krit):-
- not(dem(Krit,A,L)),!,split(L,X,Y,Z,Krit).
- split(_,[],[],[],_).
-
- /* Auswahl jener Datenfelder, die das
- Sortierkriterium bilden */
- dem([h("+",Nr)|R],A,[W|T]):-
- choose(A,X),!,n_tes(X,Nr,V),auf(A,T,V,W,R).
- dem([h("-",Nr)|R],A,[W|T]):-
- choose(A,X),!,n_tes(X,Nr,V),ab(A,T,V,W,R).
- dem([],_,_).
-
- /* Festlegung, welches Prädikat der Datenbank
- die zu sortierenden Datensätze enthält */
- choose(selektiert(X),X).
- choose(daten(X),X).
-
- /* aufsteigend sortieren */
- auf(_,_,s(V),s(W),_):- V<W,!.
- auf(_,_,i(V),i(W),_):- V<W,!.
- auf(_,_,r(V),r(W),_):- V<W,!.
- auf(A,H,V,V,R):- dem(R,A,H).
- /* das erste Sortierkriterium reicht
- für die Sortierreihenfolge nicht aus */
-
- /* absteigend sortieren */
- ab(_,_,s(V),s(W),_):- V>W,!.
- ab(_,_,i(V),i(W),_):- V>W,!.
- ab(_,_,r(V),r(W),_):- V>W,!.
- ab(A,H,V,V,R):- dem(R,A,H).
-
- sammle(_,[],[]).
- sammle(H,[V|T],[h(_,Nr)|R]):-
- choose(H,Y),n_tes(Y,Nr,V),sammle(H,T,R).
-
- /* von 'findall' benötigt */
- wahl1(selektiert(X)):- selektiert(X).
- wahl2(daten(X)):- daten(X).
-
- mode1(g(0,[]))./* keine Selektierkriterien eingegeben */
- mode2([]). /* keine Sortierkritererien eingegeben */
-
- /* Ausgabe aller Datensätze in unsortierter Form */
- out1:-
- daten(X),n(N),schreibe(X,N),retract(n(N)),N1=N+1,
- asserta(n(N1)),nl,fail.
- out1.
-
- schreibe([],N):- warte(N).
- schreibe([s(X)|T],N):- !,write(X," "),schreibe(T,N).
- schreibe([i(X)|T],N):- !,write(X," "),schreibe(T,N).
- schreibe([r(X)|T],N):- write(X," "),schreibe(T,N).
-
- warte(N):- N mod 10 = 0,readchar(_).
- warte(_).
-
- GOAL
- run