1 / 31

Obiektowe języki zapytań

Obiektowe języki zapytań. Wykładowca : Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl. Wykład 07: Stos środowisk, rezultaty zapytań, funkcja nested.

Download Presentation

Obiektowe języki zapytań

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl Wykład 07: Stos środowisk, rezultaty zapytań, funkcja nested

  2. Stos środowisk environment stack • Pojęcie stosu środowisk pojawiło się w informatyce w latach 60-tych. • Od tego czasu stos ten jest elementem konstrukcji większości znanych języków, włączając Pascal, C/C++, Smalltalk, Java, itd. • Idea tego stosu jest znana wszystkim konstruktorom języków oraz większości programistów programujących w w/w językach. • Idea jest prosta i oczywista, ale nie jest często dostatecznie dobrze objaśniona w podręcznikach. • Specjaliści z zakresu baz danych rzadko rozumieją, po co jest ten stos i jakie ma własności. • Znane języki zapytań są oparte o koncepcje ograniczone i nieadekwatne, takie jako algebra relacji, algebry obiektowe, itd. • Przy konstrukcji semantyki języków zapytań musimy wrócić do stosu środowisk. • Prześledzić jego rolę jako mechanizmu języków programowania oraz zmodyfikować jego budowę i funkcje go w taki sposób, aby odpowiadał on potrzebom związanym z definicją semantyki języków zapytań.

  3. Środowiska w językach programowania • Pojęcie środowiska (environment) działania programu oznacza zestaw wszystkich bytów programistycznych czasu wykonania (zmiennych, stałych, obiektów, funkcji, procedur, typów, klas, itd.), które są dostępne dla programisty w danym punkcie sterowania programu. • Środowisko wykonania nie jest „płaską” strukturą oraz zmienia się w trakcie działania programu. • Wygodnym sposobem zarządzania zmianami środowiska jest przyjęcie założenia, że środowisko jest podzielone na pod-środowiska, które pojawiają się i znikają w miarę przesuwania się sterowania programu. S1 S2 S2 S3 S1 S2 S1 S1 S1 sterowanie

  4. Zasady zarządzania środowiskami programu • Zasady te mają wpływ na technikę i niezawodność programowania. Są one następujące: • Środowisko lokalne danego bytu programistycznego ma priorytet w stosunku do środowiska bardziej globalnego. Np. programista koncentrujący się nad napisaniem pewnej procedury powinien mieć możliwość abstrahowania od wpływu globalnego środowiska na tę procedurę. • Zasada lokalnego kontekstu: programista piszący pewną procedurę nie może uwzględnić w niej tych (nieznanych) elementów środowiska wykonania, które pojawią się w momencie wywołania tej procedury. • Zasada dowolnego zagnieżdżania wołań procedur: programista piszący procedurę może bez ograniczeń koncepcyjnych wołać w niej inne procedury. W szczególności, dopuszczalne są dowolne rekurencyjne wołania, pośrednie lub bezpośrednie.

  5. Realizacja zarządzania środowiskami • Przyjęcie tych zasad prowadzi do pojęcia stosu środowisk (określanego także jako stos wołań, call stack), czyli struktury danych odpowiedzialnej za kontrolowania zmianami środowiska wykonania programów. • W językach programowania cel, działanie i organizacja mechanizmu stosu środowisk jest dobrze rozpoznane. Stos ten jest odpowiedzialny za: • kontrolowanie zakresów nazw zmiennych i wiązanie tych nazw; • przechowywanie wartości lokalnych zmiennych funkcji, procedur lub metod; • przechowywanie wartości parametrów aktualnych funkcji i procedur; • przechowywanie tzw: śladu powrotu, tj. adresu instrukcji, do której ma przejść sterowanie po zakończeniu działania funkcji, procedury lub metody. • Stos środowisk jest strukturą danych przechowywaną w pamięci operacyjnej (lub wirtualnej). Jest on podzielony na części, które będziemy określać jako sekcje, przy czym kolejność sekcji jest istotna.

  6. Działanie stosu środowisk • Stos jest zarządzany zgodnie z wołaniami procedur, funkcji, metod, itd. oraz wejściem sterowania w tzw. bloki programu. • Nowa sekcja (tzw. zapis aktywacji, activation record) pojawia się na wierzchołku stosu w momencie wejścia sterowania programu w procedurę (funkcję, metodę) oraz w momencie wejścia sterowania w blok. • Sekcja ta zawiera wartości lokalnych zmiennych, wartości parametrów oraz (dla procedur, funkcji i metod) ślad powrotu. • Zatem nowa sekcja na stosie odpowiada każdemu wołaniu procedury, funkcji lub metody, lub wejściu sterowania w nowy blok. • Sekcja ta jest usuwana z wierzchołka stosu w momencie zakończenia procedury (funkcji, metody) oraz w momencie wyjścia z bloku. • Wszystkie lokalne zmienne zadeklarowane w aktualnie wykonywanej procedurze (funkcji, metodzie) oraz jej parametry są przechowywane na wierzchołku tego stosu.

  7. Ilustracja działania stosu środowisk Procedura p1 wywołuje procedurę p2, która wywołuje procedurę p3 Wywołanie p3 Sekcja lokalnych danych i parametrów procedury p3 Sekcja lokalnych danych i parametrów procedury p2 Sekcja lokalnych danych i parametrów procedury p1 ... Sekcja danych globalnych Wywołanie p2 Wyjście z p3 Sekcja lokalnych danych i parametrów procedury p2 Sekcja lokalnych danych i parametrów procedury p1 ... Sekcja danych globalnych Sekcja lokalnych danych i parametrów procedury p2 Sekcja lokalnych danych i parametrów procedury p1 ... Sekcja danych globalnych Wywołanie p1 Wyjście z p2 Sekcja lokalnych danych i parametrów procedury p1 ... Sekcja danych globalnych Sekcja lokalnych danych i parametrów procedury p1 ... Sekcja danych globalnych Wyjście z p1 ... Sekcja danych globalnych ... Sekcja danych globalnych czas

  8. Wiązanie (1) binding • Wiązanie jest to zastępowanie nazw występujących w tekście programu na byty programistyczne czasu wykonania, np. na adresy RAM, identyfikatory obiektów, adresy startowe procedur, itd. • Przykładowo, wiązanie nazwy zmiennej x oznacza zastąpienie tej nazwy przez adres RAM, gdzie przechowywana jest wartość zmiennej x. • Wiązanie może być wczesne lub statyczne (early binding, static binding), czyli odbywa się w czasie kompilacji, albo późne lub dynamiczne (late binding, dynamic binding), czyli odbywa się w czasie wykonania.

  9. Wiązanie (2) binding • Wiązanie nazw na stosie środowiskowym odbywa się więc wg prostej zasady: • poszukuje się wartości opatrzonej tą nazwą w sekcji na wierzchołku stosu; • jeżeli na wierzchołku takiej nazwy nie ma, poszukuje się takiej wartości w sekcji poniżej; • proces ten jest kontynuowany aż do znalezienia wartości opatrzonej tą nazwą, ale z uwzględnieniem reguł zakresu (scoping rules), które nakazują omijanie pewnych sekcji stosu; • jeżeli nazwa nie jest odnaleziona na stosie, wówczas poszukiwana jest ona wśród zmiennych globalnych (ew. tzw. zmiennych statycznych), bibliotek funkcji i zmiennych/stałych środowiskowych. Można uważać, że tego rodzaju globalne własności znajdują się na dole stosu środowisk. • Abstrahujemy od wiązania statycznego, zakładając, że wszelkie wiązania zachodzą podczas czasu wykonania. • wiązanie statyczne traktujemy jako rodzaj optymalizacji.

  10. Przykładowa sytuacja na stosie środowisk Wykonywany jest blok l w procedurze p2 wywołanej z p1. Kolejność poszukiwania wiązania dla zmiennej g procedure p1( x, y ) { deklaracje zmiennych a, b; ... call p2( 55, 83 ); ... } procedure p2( z, t ) { deklaracje zmiennych c,d; ... { (* blok l *) deklaracje zmiennych e, f; g := 75; ... }; ... } Wierzchołek stosu Zmienne e, f zadeklarowane wewnątrz bloku l Zmienne c, d i parametry z(55), t(83) procedury p2 Zmienne a, b i parametry x, y procedury p1 ......... Zmienne i inne byty globalne Dół stosu

  11. Dlaczego przy wiązaniu omijamy niektóre sekcje? • Reguła zakresu: z wnętrza procedury p2 (i bloku b) nie mogą być widoczne zmienne i parametry procedury p1. • Procedury p1 i p2 mogą być pisane przez różnych programistów, w różnym czasie, zatrudnionych przez różne firmy. • Programista piszący p2 nie ma pojęcia, jakie nazwy lokalnych zmiennych będą użyte podczas pisania p1. • Nie może mieć jakiejkolwiek możliwości odwołania się do zmiennych procedury p1. Każde takie odwołanie wynikałoby z przypadkowej zgodności nazw, np. wskutek błędu. • Zatem najlepiej "na chwilę" ukryć środowisko wewnętrzne p1. • Jest to zasada określana niekiedy jako statyczna lub leksykalna kontrola zakresu (static scoping, lexical scoping). • Zasada ta mówi, że programista nie może mieć możliwości odwołania się do tych bytów programistycznych, które są dla niego niewidoczne lub nieznane podczas pisania programu.

  12. Statyczna kontrola zakresu dla modułów • p1 woła p2 . Procedura p1 znajduje się wewnątrz modułu m1, zaś procedura p2 znajduje się wewnątrz modułu m2. Wykonywany jest blok b wewnątrz p2. • Podobnie dla języków obiektowych (do tego tematu dojdziemy). Kolejność poszukiwania zmiennej x Wierzchołek stosu Zmienne zadeklarowane wewnątrz bloku b Zmienne i parametry procedury p2 Prywatne i publiczne własności modułu m2 Własności importowane przez moduł m2 Zmienne i parametry procedury p1 Prywatne i publiczne własności modułu m1 Własności importowane przez moduł m1 ......... Referencje do wszystkich modułów Referencje do własności środowiska globalnego Dół stosu

  13. Po co jest mechanizm stosu środowiskowego? (1) • Abstrakcja i hermetyzacja: wnętrze napisanej procedury (funkcji, metody) zostaje ukryte przed programistami, którzy jej użyją. Procedura jest widoczna wyłącznie poprzez jej interfejs (tzw. sygnaturę). • Izolacja: programiści piszący różne procedury nie muszą o sobie wiedzieć ani nie muszą między sobą uzgadniać nazw lokalnych zmiennych. • Semantyczna niezależność i ponowne użycie: procedura może być wywołana z wielu miejsc. Może być także używana w wielu aplikacjach. • Wywoływanie procedur z innych procedur, włączając wołania rekurencyjne. Dzięki temu, że sekcja stosu jest przypisana do wołania procedury, nie zachodzi konflikt przy wywołaniach procedur z procedur; w szczególności, procedura może bez ograniczeń wywołać samą siebie. • Przy założeniu, że pamięć przeznaczona na stos jest nieograniczona, co nie ma miejsca w typowych językach programowania. • Niekiedy stos jest zorganizowany z użyciem pamięci wirtualnej, co minimalizuje problem przepełnienia stosu.

  14. Po co jest mechanizm stosu środowiskowego? (2) • Spójne zarządzanie nazwami użytymi w programie. Przestrzeń użytych nazw jest ściśle kontrolowana, zaś nazwy są wiązane do bytów programistycznych czasu wykonania według ścisłych reguł. • Realizacja metod transmisji parametrów: wartości parametrów oraz inne ich własności są odkładane w lokalnych sekcjach stosu, dzięki czemu możliwy jest spójny dostęp i zarządzanie parametrami oraz realizacja metod transmisji parametrów, takich jak wołanie przez wartość (call-by-value) lub wołanie przez referencję (call-by-reference). • Podane motywacje mają znaczenie dla języków zapytań, pozwalając zrealizować takie ich założenia jak: możliwość dowolnego zagnieżdżania zapytań, możliwość powoływania lokalnych nazw wewnątrz zapytań, możliwość używania nazw z bazy danych łącznie z nazwami zmiennych programistycznych, nazwami procedur, funkcji i metod. • Nie uwzględnienie mechanizmu stosu środowiskowego w typowych podejściach do języków zapytań, takich jak algebra relacji, rachunek relacyjny, logika matematyczna, itd. z góry skazuje je na ograniczenia.

  15. Stos statyczny i dynamiczny • W typowych językach nazwy występujące w programie są drugiej kategorii programistycznej: nie są dostępne podczas wykonania programu. • Dla takich języków stos środowiskowy musi istnieć w dwóch postaciach: stos zarządzany podczas kompilacji (stos statyczny), oraz stos czasu wykonania (stos dynamiczny). • Wiązanie nazw odbywa się początkowo na stosie statycznym i ostatecznie na dynamicznym. • Podczas kompilacji stos statyczny symuluje działanie stosu dynamicznego - jest podwyższany lub skracany w miarę postępu analizy syntaktycznej. • Stos statyczny przechowuje nazwy bytów programistycznych, ich sygnatury, oraz informacje o ich reprezentacji. Wiązanie nazw nie jest bezwzględne, lecz relatywne, z dokładnością do odległości (mierzonej w bajtach) położenia reprezentacji danej wartości od wierzchołka stosu dynamicznego. • Dopiero podczas wykonania następuje ostateczne obliczenie adresu ulokowania danego bytu programistycznego np. poprzez odjęcie adresu relatywnego od aktualnego rozmiaru stosu.

  16. Stos środowisk w SBA (1) • Stos środowisk dostosujemy do wymagań semantyki języków zapytań oraz konstrukcji pochodnych, takich jak perspektywy, procedury bazy danych, itd. Stos będzie spełniać następujące założenia: • Będzie zgodny z modelami składu M0 - M3. • Będzie w jednorodny sposób traktował dane indywidualne i kolekcje. • Maksymalny rozmiar stosu nie będzie implementacyjnie ograniczony. • Stos będzie składał się z sekcji, gdzie każda sekcja będzie przechowywać informację o pewnym środowisku czasu wykonania, np. środowisku wywołania pewnej funkcji, procedury lub metody, środowisku wnętrza pewnego obiektu, środowisku wnętrza pewnej klasy, środowisku obiektów bazy danych, itd. Rozmiar sekcji nie będzie ograniczony. • Na dole stosu umieszczone będą sekcje globalne, do których należą globalne zmienne aplikacji, baza danych, wspólne biblioteki procedur i funkcji, oraz zmienne środowiskowe systemu komputerowego.

  17. Stos środowisk w SBA (2) • Stos będzie więc przechowywał pełną informację niezbędną do wiązania dowolnej nazwy, która może wystąpić w zapytaniu, perspektywie, procedurze, trygerze lub programie aplikacyjnym. • Stos będzie w jednakowy sposób traktował zarówno dane trwałe (persistent) przechowywane w bazie danych, dane chwilowe będące danymi lokalnymi wywoływanych procedur, funkcji i metod, dane chwilowe będące danymi globalnymi aplikacji, oraz aktualne parametry procedur lub metod. • Stos będzie także miejscem przechowywania informacji o definicjach wprowadzanych w zapytaniach lub w programach. M.in. będzie on przechowywał informację o tzw. „synonimach” lub „zmiennych korelacyjnych” (w SQL lub OQL), zmiennych związanych kwantyfikatorami, zmiennych używanych w iteratorach „for each”, itd. • W odróżnieniu od języków programowania, gdzie stos jest jednocześnie składem wartości zmiennych, nasz stos jest strukturą różną od składu obiektów. Powodem jest to, że w budowanej przez nas semantyce odwołania do tego samego obiektu mogą pojawić się w różnych sekcjach stosu.

  18. Binder binder • Podstawową strukturą przechowywaną na stosie środowisk jest binder. • Binder jest parą <n, x>, gdzie n jest zewnętrzną nazwą (nazwą zmiennej, stałej, obiektu, funkcji, perspektywy, procedury, metody, itd.), zaś x jest bytem czasu wykonania (zwykle referencją do obiektu). • Parę <n, x> będziemy zapisywać n( x ). • Definicję tę uogólnimy. • Koncepcja bindera jest bardzo prosta. Zadaniem bindera n(x) jest wiązanie, czyli zastąpienie nazwy n występującej w zapytaniu lub programie na wartość x, będącą bytem czasu wykonania. • Dla dowolnej nazwy występującej w programie musi być na stosie odpowiedni binder, który zamieni tę nazwę na byt czasu wykonania. • Nazwa, dla której odpowiadający jej binder nie istnieje, nie może być związana, czyli jest błędna. • Przy luźnych modelach składu (tzw. półstrukturalnych, semistructured) możemy uznać, że wiązanie takiej nazwy jest puste (jest pustym zbiorem).

  19. Rola binderów • Uogólnienie: Binder jest parą n(x), gdzie n może być dowolną zewnętrzną nazwą definiowaną przez programistę, użytkownika, projektanta aplikacji, projektanta bazy danych, itp., zaś x może być dowolnym rezultatem zwracanym przez zapytanie. • W podejściu stosowym do języków zapytań stos środowisk składa się z sekcji odpowiadających poszczególnym środowiskom czasu wykonania. • Sekcja jest zbiorem binderów do bytów programistycznych odpowiadającego jej środowiska. • W budowanej przez nas semantyce bindery będą miały także inne zastosowania, w szczególności, będą niekiedy zwracane jako rezultaty zapytań. • Stos środowiskowy będziemy oznaczać ENVS (ENVironment Stack).

  20. Przykładowy skład i127 X i128 Y i17 Dział Obiekty ulotne i1 Prac i5 Prac i9 Prac i22 Dział Obiekty trwałe

  21. Przykładowy ENVS Prac(i1) X(i127) Y(i128) N(5) I("Maria") ......... Nazwisko(i10) Zarobek(i11) Adres(i12) PracujeW(i16) ......... Bindery do obiektów/zmiennych nietrwałych aktualnej sesji użytkownika Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Bindery do globalnych funkcji bibliotecznych Bindery do zmiennych i funkcji środowiska komputerowego Sekcja chwilowa przetwarzania Sekcja chwilowa przetwarzania - własności lokalne wywołanej metody Sekcja chwilowa przetwarzania - własności wnętrza aktualnie przetwarzanego obiektu Prac Sekcje danych globalnych Sekcja bazy danych

  22. Pojęcie stanu • Pojedyncza referencja jest szczególnym przypadkiem rezultatu zapytania. • W ten sposób, poprzez definicję składu obiektów i stosu ENVS uzyskaliśmy precyzyjną definicje pojęcia stanu. • W podejściu stosowym pojęcie stanu (dziedzina Stan) jest definiowane jako stan składu obiektów plus stan stosu środowisk. • Brak pojęcia stanu jest bardzo poważną wadą wielu koncepcji i modeli obiektowych, w szczególności standardów SQL-99, XQuery i ODMG. • Zgodnie z wcześniejszymi definicjami, semantyka zapytania jest funkcją odwzorowującą stan, czyli skład obiektów oraz stan ENVS, w rezultat. • Odwzorowaniem, które będzie podstawą dalszych definicji, jest semantyka pojedynczej nazwy występującej w zapytaniu lub w programie. • Czynność ewaluacji takiej nazwy nosi nazwę wiązania. • Wiązanie odbywa się na ENVS zgodnie z regułą stosu, które nakazuje przeszukiwanie stosu od jego wierzchołka w kierunku jego podstawy, z pominięciem niektórych sekcji.

  23. Reguły wiązania nazw • Zasady przeszukiwania stosu i wyznaczania rezultatu wiązania są następujące: • Dla wiązanej nazwy n, ENVS jest przeszukiwany aż do znalezienia sekcji, w której znajduje się binder oznaczony nazwą n. Po znalezieniu takiej sekcji wyszukiwanie jest zakończone. • Wszystkie bindery z tej sekcji oznaczone nazwą n tworzą rezultat przeszukiwania. • Rezultat wiązania uzyskuje się poprzez odrzucenie ze znalezionych binderów nazwy n i pozostawienie wyłącznie wartości tych binderów.

  24. Mechanizm przeszukiwania stosu - funkcja bind start przeszukiwania stosu • bind( nazwa ) - funkcja wiązania nazw: • bind( Prac ) = i1 • bind( Y ) = i128 • bind( I ) = "Anna" • bind( Zarobek ) = i11 • bind( Dział ) = { i17, i22 } Prac(i1) X(i127) Y(i128) N(5) I("Anna") ......... Nazwisko(i10) Zarobek(i11) Adres(i12) PracujeW(i16) ......... Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) ......... Binder Prac(i1) znajduje się w dwóch sekcjach stosu, ale w tym przypadku wiązanie nazwy Prac zwróci i1, a nie {i1, i5, i9 }.

  25. Rezultaty zwracane przez zapytania • Oprócz referencji i wartości atomowych zapytania mogą zwrócić bindery. • Uogólnienie podanych założeń prowadzi do następującej rekurencyjnej definicji dziedziny Rezultat: • Atomowa wartość należąca do V (np. 3, "Kowalski", TRUE, itd.) należy do dziedziny Rezultat. • Rreferencja do obiektu (inaczej identyfikator obiektu) dowolnego typu należąca do I należy do dziedziny Rezultat. W szczególności, do dziedziny Rezultat należą referencje do metod, procedur, funkcji, perspektyw, itd. • Jeżeli xRezultat, zaś nN jest dowolną nazwą, wówczas para n(x) należy do dziedziny Rezultat. Taki rezultat będziemy nazywać nazwaną wartością; w innym kontekście został on już określony jako binder. • Jeżeli x1, x2, x3, ...Rezultat, wówczas struct{ x1, x2, x3, ...} Rezultat. struct jest konstruktorem struktury, czyli pewnym dodatkowym atrybutem (flagą) rezultatu. Kolejność elementów w strukturze ma znaczenie. • Jeżeli x1, x2, x3, ...Rezultat, wówczas bag{ x1, x2, x3, ...} Rezultat oraz sequence{ x1, x2, x3, ...} Rezultat.

  26. Przykłady zbioru Rezultat • Atomowe: • 25, "Kowalski", i11, i18 • Złożone: • struct{i1, i56} • sequence{ i1, i6, i11} • bag{ struct{i1, i56}, struct{i6, i72}, struct{i11, i72}} • bag{struct{n("Kowalski"), Zarobek(2500), d(i56)}} • bag{struct{ Dział(i56), Prac( bag{ struct{ n("Nowak"), s(i9) }, struct{ n("Stec" ), s(i14) }})} • Przy pomocy podanych konstruktorów można tworzyć struktury przypominające obiekty. Nie są one jednak obiektami, ponieważ nie można im przypisać własnych identyfikatorów i nie można ich związać z istniejącą lub nową klasą. Używając terminologii ODMG, rezultaty zapytań są literalami. Takiej terminologii nie będziemy stosować.

  27. Rezultaty zapytań zapisane jako tablice bag{ struct{i1, i56}, struct{i6, i72}, struct{i11, i72}} bag{ struct{ n("Nowak"), s(i9)}, struct{ n("Stec"), s(i14)}, struct{ n("Mikuła" ), s(i18)}} sequence{ i1, i6, i11} n "Nowak" "Stec" "Mikuła" s i9 i14 i18 i1 i6 i11 i56 i72 i72 i1 i6 i11

  28. Otwieranie nowego zakresu na stosie środowisk • W klasycznych językach programowania otwieranie nowego zakresu na wierzchołku ENVS następuje w momencie wywołania procedury (funkcji, metody) lub w momencie wejścia sterowania w nowy blok. Skasowanie tej sekcji następuje w momencie zakończenia działania procedury (funkcji, metody) lub w momencie wyjścia sterowania z bloku. • Do klasycznych sytuacji otwierania nowego zakresu na ENVS dołączymy nową. Stanowi ona istotę podejścia stosowego do języków zapytań. Pewne operatory występujące w zapytaniach (zwane niealgebraicznymi) działają na stosie podobnie do wywołań bloków programów. • Np. w zapytaniu języka SBQL: Prac where (Nazwisko = ”Kowalski” andZarobek > 1000) część (Nazwisko = ”Kowalski” andZarobek > 1000) jest blokiem, który jest ewaluowany w nowym środowisku określonym przez “wnętrze” obiektu Prac aktualnie testowanego przez operator where. • Na stos ENVS jest wkładana nowa sekcja zawierająca bindery do wszystkich wewnętrznych własności (atrybutów, metod, itd.) tego obiektu Prac.

  29. Ilustracja otwierania nowego zakresu Nazwisko(i10) Zarobek(i11) Adres(i12) PracujeW(i16) PRAC (i1) PRAC (i5) PRAC(i9) DZIAŁ (i17) DZIAŁ (i22) Operator where iteruje po rezultacie zapytania PRAC. W każdej iteracji wkłada (i po ewaluacji zdejmuje) sekcję stosu zawierającą bindery do wnętrza kolejnego obiektu PRAC. PRAC where (Nazwisko = ”Kowalski” and Zarobek > 1000) wiązanie wiązanie wiązanie PRAC (i1) PRAC (i5) PRAC(i9) DZIAŁ (i17) DZIAŁ (i22) Stos w momencie ewaluacji zapytania PRAC. Ewaluacja (wiązanie) nazwy PRAC zwraca {i1, i5, i9} Stos w momencie ewaluacji pod-zapytania (Nazwisko = ”Kowalski” and Zarobek > 1000) dla trzeciego obiektu PRAC. Ewaluacja (wiązanie) nazwy Nazwisko zwraca i10. Ewaluacja (wiązanie) nazwy Zarobek zwraca i11.

  30. Funkcja nested i9Prac i10 Nazwisko ”Barski” i11 Zarobek 2000 i12 Adres i13 Miasto ”Radom” i14 Ulica ”Wolska” i15 NrDomu 12 i16 PracujeW • Intencją jest zdefiniowanie funkcji, której argumentem jest referencja do obiektu, zaś wynikiem jest wewnętrzne środowisko tego obiektu, które ma być umieszczone na ENVS. • Takie środowisko jest zbiorem binderów. • Funkcję nazwaliśmy nested. nested(i9) = { Nazwisko (i10 ), Zarobek (i11 ), Adres (i12 ), PracujeW (i16 ) }

  31. Uogólnienie funkcji nested • Dla dowolnej wartości atomowej vVnested( v ) =  (zbiór pusty). • Dla identyfikatora i obiektu atomowego (nie posiadającego podobiektów) nested( i ) = . • Dla obiektu złożonego <i, n, {<i1, n1, ...>, <i2, n2, ...>, ... , <ik, nk, ...> }> nested( i ) = { n1(i1), n2(i2), ... , nk(ik) }. • Dla identyfikatora i obiektu pointerowego <i, n, i1> dla którego istnieje w składzie obiekt < i1, n1, ...> nested( i ) = { n1(i1)}. • Dla dowolnego bindera n(x) nested( n(x) ) = { n(x) }. • Jeżeli argumentem funkcji nested jest struktura elementów, wówczas wynik jest sumą teorio-mnogościową rezultatów funkcji nested dla pojedynczych elementów tej struktury  nested( struct{ x1, x2, x3, ...}) = nested( x1 ) nested( x2 ) nested( x3 )  ...

More Related