# # Erstellung des RA-Proxy-Objekts. # Alle Anfragen laufen über dieses Objekt, # das Operationen bereitstellt, die die Logik # der relationalen Algebra implementieren. # use> !create ra:RelationalAlgebra # *1 # Definition der Relation Country. # Die Tupel bzw. Tabellenzeilen werden # als Wert-Sequenzen dargestellt. # # Die Implementierung unterstützt weder # Spaltennamen noch Spaltentypisierung. # use> \ !let Country=Set{Sequence{'Germany', 'Berlin', '80'}, Sequence{'France', 'Paris', '60'}, Sequence{'Netherlands','Amsterdam','25'}} . # *2 # Prüfe, ob die mittels let eingeführte # Variable Country eine Relation im Sinne # der vorliegenden Implementierung darstellt. # use> ?ra.isRelation(Country) true : Boolean # # siehe [*1] # use> \ !let Town=Set{Sequence{'Berlin', '4'}, Sequence{'Hamburg', '2'}, Sequence{'Koeln', '1'}, Sequence{'Paris', '9'}, Sequence{'Marseille','2'}, Sequence{'Amsterdam','2'}} . # # siehe [*2] # # isRelation(r:Set(Sequence(String))):Boolean # use> ?ra.isRelation(Town) true : Boolean # # Selektiere diejenigen Zeilen aus Country, für die gilt, # dass der Wert in Spalte 3 die Bedingung erfüllt, kleiner oder # gleich (#LE) 60 zu sein. # # selectV(col:Integer, cmp:CmpE, value:String, r:Set(Sequence(String))):Set(Sequence(String)) # # use> ?ra.selectV(3,#LE,'60',Country) Set{Sequence{'France', 'Paris', '60'}, Sequence{'Netherlands','Amsterdam','25'}} : Set(Sequence(String)) # # Selektiere diejenigen Zeilen aus Country, für die gilt, # dass der Wert in Spalte col1 größer ist als der Wert in Spalte col2. # # selectC(col1:Integer, cmp:CmpE, col2:Integer, r:Set(Sequence(String))):Set(Sequence(String)) # # use> ?ra.selectC(1,#GT,2,Country) Set{Sequence{'Germany', 'Berlin', '80'}, Sequence{'Netherlands','Amsterdam','25'}} : Set(Sequence(String)) # # Wähle über die gesamte Relation Country Spalte # 3 sowie 1 aus und gib eine entsprechende Ergebnisrelation zurück. # # project(cols:Sequence(Integer), r:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.project(Sequence{3,1},Country) Set{Sequence{'25','Netherlands'}, Sequence{'60','France' }, Sequence{'80','Germany'} } : Set(Sequence(String)) # # Bilde das Kartesische Produkt von Country und Town. # # product(r1:Set(Sequence(String)), r2:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.product(Country,Town) Set{Sequence{'France', 'Paris', '60', 'Amsterdam', '2'}, Sequence{'France', 'Paris', '60', 'Berlin', '4'}, Sequence{'France', 'Paris', '60', 'Hamburg', '2'}, Sequence{'France', 'Paris', '60', 'Koeln', '1'}, Sequence{'France', 'Paris', '60', 'Marseille', '2'}, Sequence{'France', 'Paris', '60', 'Paris', '9'}, Sequence{'Germany', 'Berlin', '80', 'Amsterdam', '2'}, Sequence{'Germany', 'Berlin', '80', 'Berlin', '4'}, Sequence{'Germany', 'Berlin', '80', 'Hamburg', '2'}, Sequence{'Germany', 'Berlin', '80', 'Koeln', '1'}, Sequence{'Germany', 'Berlin', '80', 'Marseille', '2'}, Sequence{'Germany', 'Berlin', '80', 'Paris', '9'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Amsterdam', '2'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Berlin', '4'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Hamburg', '2'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Koeln', '1'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Marseille', '2'}, Sequence{'Netherlands', 'Amsterdam', '25', 'Paris', '9'}} : Set(Sequence(String)) # ## # use> ?ra.project(Sequence{1,2,5}, ra.selectC(2,#EQ,4, ra.product(Country,Town))) Set{Sequence{'France', 'Paris', '9'}, Sequence{'Germany', 'Berlin', '4'}, Sequence{'Netherlands', 'Amsterdam', '2'}} : Set(Sequence(String)) # # Bilde die Differenz von zwei Relationen. # # minus(r1:Set(Sequence(String)), r2:Set(Sequence(String))):Set(Sequence(String)) # # (Anm: die beiden ra.project-Aufrufe liefern jeweils eine Relation.) # use> \ ?ra.minus(ra.project(Sequence{1},Town), ra.project(Sequence{2},Country)) . Set{Sequence{'Hamburg' }, Sequence{'Koeln' }, Sequence{'Marseille'}} : Set(Sequence(String)) # # Bilde die Vereinigung von zwei Relationen. # # union(r1:Set(Sequence(String)), r2:Set(Sequence(String))):Set(Sequence(String)) # # (Anm: Town sowie der ra.project-Aufruf liefern jeweils eine Relation.) # use> ?ra.union(Town,ra.project(Sequence{1,3},Country)) Set{Sequence{'Amsterdam', '2'}, Sequence{'Berlin', '4'}, Sequence{'France', '60'}, Sequence{'Germany', '80'}, Sequence{'Hamburg', '2'}, Sequence{'Koeln', '1'}, Sequence{'Marseille', '2'}, Sequence{'Netherlands', '25'}, Sequence{'Paris', '9'}} : Set(Sequence(String)) # ## # use> -- project[1](Country) - project[1](select[3 gt 6](Country,Country)) # ## # use> \ ?ra.minus(ra.project(Sequence{1},Country), ra.project(Sequence{1}, ra.selectC(3,#LT,6,ra.product(Country,Country)))) . Set{Sequence{'Germany'}} : Set(Sequence(String)) # ## # use> \ !let Job=Set{Sequence{'Ada','Analysis'}, Sequence{'Ada','Design' }, Sequence{'Bea','Analysis'}, Sequence{'Bea','Design' }, Sequence{'Bea','Coding' }, Sequence{'Cyd','Design' }, Sequence{'Cyd','Coding' }} . # ## # use> -- R(A,B), S(B): project[A](R)-project[A](product(project[A](R),S)-R) # ## # use> \ ?ra.minus(ra.project(Sequence{1},Job), ra.project(Sequence{1}, ra.minus(ra.product(ra.project(Sequence{1},Job), ra.project(Sequence{2},Job)), Job))) . Set{Sequence{'Bea'}} : Set(Sequence(String)) # # Bilde den Verbund über Country und Town unter dem # Vergleich #EQ der 2. Spalte von Country und der 1. Spalte von # Town. # # join(r1:Set(Sequence(String)), col1:Integer, cmp:CmpE, col2:Integer, r2:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.join(Country,2,#EQ,1,Town) Set{Sequence{'France', 'Paris', '60', 'Paris', '9'}, Sequence{'Germany', 'Berlin', '80', 'Berlin', '4'}, Sequence{'Netherlands', 'Amsterdam','25', 'Amsterdam', '2'}} : Set(Sequence(String)) # ## # use> ?ra.project(Sequence{1,2,3,5},ra.join(Country,2,#EQ,1,Town)) Set{Sequence{'France', 'Paris', '60', '9'}, Sequence{'Germany', 'Berlin', '80', '4'}, Sequence{'Netherlands', 'Amsterdam', '25', '2'}} : Set(Sequence(String)) # # Bilde den natürlichen Verbund über Country und Town unter dem # Vergleich der 2. Spalte von Country und der 1. Spalte von Town. # # natjoin(r1:Set(Sequence(String)), cols1:Sequence(Integer), cols2:Sequence(Integer), r2:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.natjoin(Country,Sequence{2},Sequence{1},Town) Set{Sequence{'France', 'Paris', '60', '9'}, Sequence{'Germany', 'Berlin', '80', '4'}, Sequence{'Netherlands', 'Amsterdam', '25', '2'}} : Set(Sequence(String)) use> ?let Age=Set{Sequence{'Ada', 'Apple', '42'}, Sequence{'Bea', 'Banana', '36'}, Sequence{'Cyd', 'Cherry', '42'}, Sequence{'Dan', 'Cherry', '10'}} in let Hair=Set{Sequence{'Almond', 'Ada', 'Blonde'}, Sequence{'Banana', 'Bea', 'Black' }, Sequence{'Cherry', 'Can', 'Black' }, Sequence{'Cherry', 'Dan', 'Brown' }} in ra.natjoin(Age,Sequence{2,1},Sequence{1,2},Hair) Set{Sequence{'Bea','Banana','36','Black'}, Sequence{'Dan','Cherry','10','Brown'}} : Set(Sequence(String)) # # Bilder die Schnittmenge zweier Relationen Rainy und Sunny. # # intersect(r1:Set(Sequence(String)), r2:Set(Sequence(String))):Set(Sequence(String)) # use> ?let Rainy=Set{Sequence{'Oslo'},Sequence{'London'},Sequence{'Berlin'}} in let Sunny=Set{Sequence{'Berlin'},Sequence{'Rome'},Sequence{'Madrid'}} in ra.intersect(Rainy,Sunny) Set{Sequence{'Berlin'}} : Set(Sequence(String)) # # Liefere den Maximalwert der 3. Spalte der Relation Country. # # max(col:Integer, r:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.max(3,Country) Set{Sequence{'Germany','Berlin','80'}} : Set(Sequence(String)) # # Liefere den Minimalwert der 3. Spalte der Relation Country. # # min(col:Integer, r:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.min(3,Country) Set{Sequence{'Netherlands','Amsterdam','25'}} : Set(Sequence(String)) # ## # use> ?ra.max(2,Town) Set{Sequence{'Paris','9'}} : Set(Sequence(String)) # ## # use> ?ra.min(2,Town) Set{Sequence{'Koeln','1'}} : Set(Sequence(String)) # # Liefere sequentiell alle Werte der Relation Country. # # allValues(r:Set(Sequence(String))):Set(Sequence(String)) # use> ?ra.allValues(Country) Set{Sequence{'25'}, Sequence{'60'}, Sequence{'80'}, Sequence{'Amsterdam'}, Sequence{'Berlin'}, Sequence{'France'}, Sequence{'Germany'}, Sequence{'Netherlands'}, Sequence{'Paris'}} : Set(Sequence(String)) # ## # use> ?ra.allValues(Town) Set{Sequence{'1'}, Sequence{'2'}, Sequence{'4'}, Sequence{'9'}, Sequence{'Amsterdam'}, Sequence{'Berlin'}, Sequence{'Hamburg'}, Sequence{'Koeln'}, Sequence{'Marseille'}, Sequence{'Paris'}} : Set(Sequence(String)) # ## # use> ?ra.union(ra.allValues(Country),ra.allValues(Town))->flatten() Set{'1','2','25','4','60','80','9','Amsterdam','Berlin','France', 'Germany','Hamburg','Koeln','Marseille','Netherlands','Paris'} : Set(String) # # Dividiere zwei Relationen anhand der 1. Spalte. # # divide(colNum:Integer, r1:Set(Sequence(String)), r2:Set(Sequence(String))):Set(Sequence(String)) # # (Anm.: ra.project-Aufrauf liefert eine Relation) # use> ?ra.divide(1,Job,ra.project(Sequence{2},Job)) Set{Sequence{'Bea'}} : Set(Sequence(String)) use> !let Job=Set{Sequence{'Ada','Apple', 'UML', 'Analysis'}, Sequence{'Ada','Apple', 'UML', 'Design'}, Sequence{'Bea','Banana','UML', 'Analysis'}, Sequence{'Bea','Banana','UML', 'Design'}, Sequence{'Bea','Banana','Ruby','Coding'}, Sequence{'Cyd','Cherry','UML', 'Design'}, Sequence{'Cyd','Cherry','Ruby','Coding'}} # ## # use> ?ra.divide(2,Job,ra.project(Sequence{3,4},Job)) Set{Sequence{'Bea','Banana'}} : Set(Sequence(String)) # ## # use> ?ra.product(ra.divide(2,Job,ra.project(Sequence{3,4},Job)), ra.project(Sequence{3,4},Job)) Set{Sequence{'Bea','Banana','Ruby','Coding'}, Sequence{'Bea','Banana','UML', 'Analysis'}, Sequence{'Bea','Banana','UML', 'Design'}} : Set(Sequence(String)) # # Liefere den Divisionsrest zweier Relationen anhand der 2. Spalte. # # modulo(colNum:Integer, r1:Set(Sequence(String)),r2:Set(Sequence(String))):Set(Sequence(String)) # # (Anm.: ra.project-Aufrauf liefert eine Relation) # use> ?ra.modulo(2,Job,ra.project(Sequence{3,4},Job)) Set{Sequence{'Ada','Apple','UML','Analysis'}, Sequence{'Ada','Apple','UML','Design'}, Sequence{'Cyd','Cherry','Ruby','Coding'}, Sequence{'Cyd','Cherry','UML','Design'}} : Set(Sequence(String)) # ## # use> ?ra.divide(3,Job,ra.project(Sequence{4},Job)) Set{} : Set(Sequence(String)) # ## # use> ?ra.divide(2,ra.project(Sequence{1,2,4},Job),ra.project(Sequence{4},Job)) Set{Sequence{'Bea','Banana'}} : Set(Sequence(String))