Welcome Guest Search | Active Topics | Members | Log In

Identyfikatory wirtualne a przechowywanie referencji Options · View
habela
Posted: Friday, February 25, 2005 10:32:37 AM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
W dwóch kwestiach:
1. Co do deref to chciałbym przypomnieć, że w naszej propozycji modelowania oraz w definicjach interfejsów określamy, czy dane obiekty mogą, czy też nie mogą podlegać dereferencji. Zauważmy, że w przykładach w paperach o perspektywach chyba zawsze dla wirtualnych obiektów złożonych definicja operacji on_retrieve nie była implementowana.
Na pewno wolałbym uniknąć rozpatrywanych przez Krzyśka rozwiązań, w których wnętrze obiektu wirtualnego z punktu widzenia zdefiniowanych dlań podperspektyw oraz to wnętrze z punktu widzenia on_retrieve wyglądało odmiennie. (Chociażby z powodu zamentu, jaki to czyni dla definicji schematu!)
Wydaje się, że wymóg, aby wszystko co widoczne w obiekcie wirtualnym miało pokrycie w postaci definicji podperspektywy jest tu akceptowalną ceną.
2. Zgadzam się z Krzyśkiem, że warto próbować wyeliminować klauzulę point_to. Ale zapewne nie poprzez definiowanie wewnątrz perspektywy wskaźnika perspektywy obiektu docelowego.
Przyjrzyjmy się przykładowi od Radka:
Code:
create view StudentDef {
//inne elementy definicji

virtual_objects Student {
return (((Student1 as e) join (Student2 as f) join (Student3 asg)) where ((e.ID == f.ID) && (f.ID == g.ID))).
((deref(e.name) as name, deref(e.universityName) as universityName, deref(f.scholarship) as scholarship, deref(g.supervisior) as supervisior) as StudentGrid, e as Student1, f as Student2, g as Student3) as StudentSeed;
}


create view studyInDef{
virtual_pointers studyIn {return bag("PW", "PJWSTK", "UW") as u; }

point_to University{ return ref(University where name == StudentSeed.StudentGrid.universityName);}

on_update(newUniversity) {
if( for any (u as regName ) (regName == newUniversity.name))
StudentSeed.Student1.universityName = newUniversity.name;
else
//wyjątek("Niepoprawna aktualizacja");
}
}
//pozostałe elementy definicji
}


Nadal nie jestem przekonany. Czy doprawdy nie można by w tym konkretnym przykładzie:
- zawrzeć tego, co tu jest w point_to w ramach odpowiednio skonstruowanej virtual_pointers?
- umieścić warunku, że musi być "PW", "PJWSTK" lub "UW" wewnątrz procedury on_update?
radamus
Posted: Friday, February 25, 2005 10:33:33 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Hanka wrote:

Jeśli mamy perspektywę postaci:
Code:

create view ITHeadhunterDef {
   virtual objects { return (Headhunter where domain = “IT“) as h; }
   create view cooperatesWithDef {
      virtual objects cooperatesWith as pointer {
          return & h . supervises . Contract . signedBy . Freelancer; }
    ...
}}


To seed będzie pointerem do obiektu Freelencer. Czyli to jednak, wbrew temu co piszesz, ten konkretny przykład będzie działać.

Seed będzie pointerem? Wydaje mi się, że nie wyraziłaś sie do końca precyzyjnie. Sama przecież w pracy napisałaś (p. 95):
Hanka wrote:

Now, the view should be used in the following query:
Code:
ITHeadhunter . cooperatesWith . Freelancer . name


However, for a seed s generated by the sack cooperatesWith a function nested( s ) returns binders to internal objects of a Freelancer object, so the above query would not work correctly. To get the name(s) of freelancer(s) one should write:
Code:
ITHeadhunter . cooperatesWith . name



Czyli seed nie jest pointerem (chyba, że źle rozumiem pojęcie pointera), jest identyfikatorem obiektu w składzie. Aby rozwiązać ten problem zaproponowaś rozwiązanie:


Hanka wrote:

Virtual objects generated by a pointer view must be distinguishable from other virtual objects. Therefore, we introduce the notion of a virtual pointer identifier of the following form:
Code:
<flag “I am virtual pointer“, seed, view definition identifier >

The necessary extension of SBA is that a function nested( virtual pointer identifier ) simply changes flag in virtual object’s identifier and returns a binder with the value:
Code:
<flag “I am virtual“, seed, view definition identifier >

In this way from user’s perspective navigation through virtual pointer looks the same as navigation through any other pointer.


No to ja w takim wypadku spróbuję opisać jak to rozumiem, a Ty mnie ewentualnie naprowadź na dobry tor, jeśliby się okazało, że jestem na bocznicy. Wirtualny identyfikator, który będzie wynikiem virtual objects ma zwieszoną flagę "jestem wirtualnym pointerem". Kropka powinna spowodować, że mechanizm zachowa się jak w przypadku pointera. Czyli zamiast wykonywać nested(seed), potraktuję seed jako wartość pointera (bo tak jest). Jeśli dobrze rozumiem ten binder, który wrzucany jest na stos jako rezutat nested( virtual pointer identifier ) ma nazwę pobraną z seed'a, przy założeniu, że jest to identyfikator obiektu w składzie.
Na stos wrzucony zostanie binder o nazwie Freelancer. Oczywiście w tym wypadku nazwa Freelancer jest nazwą rzeczywistego obiektu, którą można pobrać i moja procedura point_to nazywająca wskazywany obiekt przestaje mieć sens. Rozwiązanie jest rzeczywiście eleganckie. Tylko ogranicza to czym może być seed.

Hanka wrote:

Natomiast jeśli dopuścimy, że seed dla pointera wirtualnego ma dowolną postać to możemy mieć faktycznie problem. Twoje rozwiązanie tego problemu mi się nie podoba, bo w większości przypadków będzie się to sprowadzało do zdublowania informacji zawartych w sekcji virtual objects. Być może należałoby natomiast ograniczyć to co może być seedem dla pointerów wirtualnych (np. dopuścić, że może to być referencja do obiektu lub binder zawierający referencje do obiektu)?...

Być może jest to rozwiązanie. W sumie jest to pointer, więc nie powinien zwracać byle czego. Ale co z wirtualnymi pointerami do wirtualnych obiektów? W overloadnig views jest to istotne bo dowolny obiekt może być przykryty takim view. Trzeba jeszcze na ten temat podyskutować.
subieta
Posted: Friday, February 25, 2005 10:48:36 AM

Rank: Advanced Member

Joined: 12/22/2004
Posts: 675
Points: 704
Location: Legionowo
Hanka wrote:
To nie jest prawda, ze pointery wirtualne mogą być dowolnie aktualizowne. To jest mozliwe jedynie w tak prostym przypadku jak jest tutaj omawiany, czyli w sytuacji gdy pointer wirtualny przykrywa 1:1 pointer rzeczywisty. [....] Dlatego pointery wirtualne nie powinny aktualizowane (byc moze to ograniczenie mozna zluzowac dla takiego prostego przypadku jak w omawianym przez Radka przykladzie).


Niestety nie moge sie zgodzic. Brak mozliwosci aktualizacji pointerow wirtualnych (nie majacych 1:1 odpowiednikow w pointerach rzeczywistych) bylby duzym ograniczeniem rzeczywistych sytuacji. Najbardziej spektakularna z nich dotyczy aktualizacji obiektow, ktore powstaly z relacyjnych tabel poprzez wykorzystanie zwiazkow klucz glowny/klucz obcy i zamiana takich sytuacji na wirtualne pointery. (Patrz ostatnie pomysly w pracy doktorskiej Mariusza Trzaski). W relacyjnych bazach pointerow jak wiadomo w ogole nie ma, nie ma ich takze w XML-owych, a czasami przy przyjeciu jakiegos wirtualnego modelu kanonicznego chcialoby sie je miec. Brak mozliwosci ich aktualizacji bylby powaznym ograniczniem dla wielu zastosowan. Np. w przypadku bazy relacyjnej odwzorowanej na obiektowa, aktualizacja wirtualnego pointera oznaczalaby odpowiednia aktualizacje klucza obcego. Dlaczego to mialoby byc bez sensu? Problem polega wylacznie na tym, jak to ustawic syntaktycznie i semantycznie, aby to bylo latwe dla programisty i w miare spojne z tym, co zostalo ustalone poprzednio w kwestii aktualizowalnych perspektyw.

Dokladnie taki temat (odwzorowanie relacyjnej bd w wirtualna obiektowa na gruncie aktualizowalnych perspektyw) dostal jako temat doktoratu jeden pan z Lodzi, ale na razie jego aktywnosc w tym wzgledzie nie wystapila. Moge ten temat dac komus innemu, moim zdaniem jest to piekny spektakularny temat, poniewaz baz relacyjnych jest bez liku i milo byloby robic z nich wirtualne obiektowe lub XML-owe.

Dodam jeszcze, ze takie wirtualne odwzorowanie bazy relacyjnej na pseudo-obiektowa, wystapilo w projekcie ICONS, ktorego rdzeniem byl Office Objects Portal firmy Rodan. Chlopcy-rodanowcy (prawie) poprawnie odwzorowali zwiazki klucz obcy/klucz glowny na asocjacje w sensie UML, ale zrobili to tylko dla odczytu. Jezeli ktos chcialby aktualizowac takie asocjacje, to musialby niestety aktualizowac siedzaca pod spodem relacyjna baze danych. Czyli dwa rozne schematy, dwa rozne interfejsy w jednym, co normali ludzie nazywaja niekiedy schizofrenia widzenia. Jet to oczywiscie przezroczystosc inaczej. Poniewaz m.in. z tego powodu nie polubilem Office Objects Portal, to efektem jest projekt ODRA. Zatem temat zahacza o zrodla tego projektu.
radamus
Posted: Friday, February 25, 2005 10:52:28 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
habela wrote:

Nadal nie jestem przekonany. Czy doprawdy nie można by w tym konkretnym przykładzie:
- zawrzeć tego, co tu jest w point_to w ramach odpowiednio skonstruowanej virtual_pointers?
- umieścić warunku, że musi być "PW", "PJWSTK" lub "UW" wewnątrz procedury on_update?


Można. Ale takim wypadku można Twój wniosek przenieść również na zwykłe podobiekty wirtualne.

Code:
create view BigUniversityDef {
  virtual objects BigUniversity { return (University where graduateNumber > 10000) as bu; }
 
 
  create view NameDef {
    virtual objects name { return bu.name as n; }
    on_retrieve {
      return deref(n);
    }
  }
}


Po co pisać procedurę virtual objects dla name jeżeli wszytko jet dostępne z seed'a obiektu nadrzędnego?
Przecież on_retrieve można napisać:

Code:
on_retrieve {
      return deref(bu.name);
    }


Tylko, że mając w ręku procedurę virtual_objects umieszczasz w niej definicję ziaren dla konkretnego obiektu. Dekomponujesz problem. Zwiększasz czytelność i zrozumienie rozwiązania. Taki seed obiektu nadrzędnego może być dowolnie złożony.
radamus
Posted: Friday, February 25, 2005 10:59:55 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
subieta wrote:

Niestety nie moge sie zgodzic. Brak mozliwosci aktualizacji pointerow wirtualnych (nie majacych 1:1 odpowiednikow w pointerach rzeczywistych) bylby duzym ograniczeniem rzeczywistych sytuacji. Najbardziej spektakularna z nich dotyczy aktualizacji obiektow, ktore powstaly z relacyjnych tabel poprzez wykorzystanie zwiazkow klucz glowny/klucz obcy i zamiana takich sytuacji na wirtualne pointery.


Inne przykłady jakie mi chodzą po głowie to są globalne schematy i integracja danych. Na poziomie globalnego schematu potrzebne będą związki pointerowe. Bedą one nawet na zasadzie wirtualny pointer -> wirtualny obiekt. Podobnie w overloadnig views.

subieta wrote:

Problem polega wylacznie na tym, jak to ustawic syntaktycznie i semantycznie, aby to bylo latwe dla programisty i w miare spojne z tym, co zostalo ustalone poprzednio w kwestii aktualizowalnych perspektyw.


Dokładnie tak. Cieszę się, że moja propozycja wywołała burzliwą dyskusję. Nie twierdzę, że jest najlepsza, ale może uda się wypracować nam coś lepszego.
Hanka
Posted: Friday, February 25, 2005 11:06:22 AM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
radamus wrote:

No to ja w takim wypadku spróbuję opisać jak to rozumiem, a Ty mnie ewentualnie naprowadź na dobry tor, jeśliby się okazało, że jestem na bocznicy.


To jeszcze raz, bo może się faktycznie niezbyt dobrze to opisałam - mechanizm jest następujący:
1) zapytanie & h . supervises . Contract . signedBy . Freelancer zwraca referencję do obiektu Pracownik
2) nested od tego zwróci w normalnym przypadku wnętrze obiektu Freelancer - czego my nie chcemy, bo wnętrze tego obiektu powinno się pojawić na stosie dopiero przy kolejnym nested
3) dlatego nic nie jest robione, tylko zmieniana jest flaga
4) przy następnym kroku mechanizm działa już klasycznie

Niestety jak widać w moim podejściu do pointerów wirtualnych jest trochę luk :( (im dłużej się na to patrzę tym więcej ich widzę), dlatego dobrze że ta dyskusja została na tym forum wywołana
habela
Posted: Friday, February 25, 2005 11:25:57 AM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
Dyskusja w tym wątku zrobiła się trochę wielowątkowa...
Nie podejmę się w tej chwili podsumowania dyskusji i wyodrębnienia nowego wątku, choć warto już o tym pomyśleć.
Na razie jedna krótka uwaga:
Quote:
Po co pisać procedurę virtual objects dla name jeżeli wszytko jet dostępne z seed'a obiektu nadrzędnego?
Przecież on_retrieve można napisać:

Code:
on_retrieve {
      return deref(bu.name);
    }


Tylko, że mając w ręku procedurę virtual_objects umieszczasz w niej definicję ziaren dla konkretnego obiektu. Dekomponujesz problem. Zwiększasz czytelność i zrozumienie rozwiązania. Taki seed obiektu nadrzędnego może być dowolnie złożony.


Zwiększam czytelność i zrozumiałość? Tylko tyle?
To sformułowanie mnie zdziwiło, bo zawsze zakładałem, że definicja virtual_objects nie jest tylko takim wewnętrznym utility dla programisty, pozwalającym zdekomponować sobie zadanie (jak np. metoda prywatna) i w pełni zahermetyzowanym za pomocą definicji operacji genrycznych.
Że sposób jego zorganizowania determinuje, jak będziemy mogli nawigować do podobiektów i ile podobiektów będzie związanych z danym jednym obiektem nadrzędnym (przykładem, który sugerował mi taką interpretację była definicja obiektu złożonego, pozbawiona jakichkolwiek operacji genrycznych, a mimo to pozwalająca w pełni użytecznie nawigować do swoich podobiektów wirtualnych (podperspektywy z ich sekcjami virtual_objects)).
Zakładam, że dowolnie złożony (i zagnieżdżony) element kolekcji z rezultatu zapytania w tej klauzuli -> pojedynczy obiekt wirtualny, zaś określona definicja w podperspektwie -> odpowiednia liczba podobiektów wirtualnych danego rodzaju.
Wydawało mi się intuicyjne, że np. virtual_objects dla study_In wewnątrz studenta powinno zwracać rezultat o takiej liczebności, ile pointerów study_in ma mieć dany student. W podanym przykładzie zaś zwraca po prostu kolekcję ze wszystkimi dopuszczalnymi wartościami nazw.
To jest właśnie element, którym jestem zdezorientowany.
Hanka
Posted: Friday, February 25, 2005 11:40:27 AM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
habela wrote:

Wydawało mi się intuicyjne, że np. virtual_objects dla study_In wewnątrz studenta powinno zwracać rezultat o takiej liczebności, ile pointerów study_in ma mieć dany student. W podanym przykładzie zaś zwraca po prostu kolekcję ze wszystkimi dopuszczalnymi wartościami nazw.
To jest właśnie element, którym jestem zdezorientowany.


Zgadzam się z Piotrem. Seedy powinny jednoznacznie identyfikować obiekty wirtualne. Tak jest od początku pracy nad perspektywami i chyba zmienianie tego po to, żeby zaimplementować pointery wirtualne nie ma sensu.

Generalnie, w tej chwil najbardziej sensownym rozwiązaniem wydaje mi się (tak jak pisałam wcześniej) wprowadzenie ograniczenia na to, czym może być seed dla perspektywy definiującej wirtualny pointer. Jeśli założymy, że to musi być:
- albo referencja do obiektu
- albo binder z taka referencją
Wszystko sie upraszcza (trzeba tylko wprowadzić ewentualne modyfikacje do funkcji nested dla takiego ob. pointerowego) i nie potrzebne są żadne dodatkowe sztuczki.

Z punktu widzenia programisty wydaje mi się, że takie ograniczenie nie powinno być uciążliwe, bo zazwyczaj seed takiej perspektywy i tak sprowadza się do jakiejś referencji do obiektu, o którego potem można dalej nawigować.
radamus
Posted: Friday, February 25, 2005 8:08:08 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Coś mi tu jednak dalej nie do końca pasuje...
Przypomnę definicję:
Code:
create view ITHeadhunterDef {
   virtual objects { return (Headhunter where domain = “IT“) as h; }
   create view cooperatesWithDef {
      virtual objects cooperatesWith as pointer {
          return & h . supervises . Contract . signedBy . Freelancer; }
    ...
}}


Zapytanie z pracy Hani
Code:
ITHeadhunter . cooperatesWith . Freelancer . name


Podzapytanie
Code:
ITHeadhunter . cooperatesWith
tworzy wirtualny identyfikator. Wg. pomysłu Hani:
Code:
<flag “I am virtual pointer“, seed, view definition identifier >



Hanka wrote:

1) zapytanie & h . supervises . Contract . signedBy . Freelancer zwraca referencję do obiektu Pracownik


Czyli seed'em jest referencja do obiektu Freelancer.
Teraz operator kropki przetwarza wirtualny pointer
Code:
ITHeadhunter . cooperatesWith.

Standardowo na ENVS powinniśmy wrzucić nested(seed), ale ...

Hanka wrote:

2) nested od tego zwróci w normalnym przypadku wnętrze obiektu Freelancer - czego my nie chcemy, bo wnętrze tego obiektu powinno się pojawić na stosie dopiero przy kolejnym nested

Zgadza się, my chcemy, żeby na stodie pojawił się binder o nazwie Freelancer. Wartością tego bindera powina być referencja do obiektu Freelancer. Tak byłoby przy rzeczywistym pointerze.
Hanka wrote:

3) dlatego nic nie jest robione, tylko zmieniana jest flaga

No nie do końca, bo na stos musimy wrzucić binder o nazwie Freelancer. Według Hani zmieniana jest flaga. I teraz mamy zwykły wirtualny identyfikator.
Code:
<flag “I am virtual“, seed, view definition identifier >

Tylko po co? Żeby na stos wrzucić binder o nazwie Freelancer, którego wartością będzie ten nowy wirtualny identyfikator? To oznaczałoby, że następna część naszego zapytania,
Code:
ITHeadhunter . cooperatesWith . Freelancer

zwróciłaby wirtualny identyfykator. Ale przecież może zwrócić rzeczywisty identyfikator obiektu Freelancer. Oczywiście to zadziała bo teraz nested(seed) wrzuci na ENVS wnętrze obiektu Freelancer, ale już zapytanie:

Code:
delete ITHeadhunter . cooperatesWith . Freelancer


nie zadziała bo mamy do czynienia z identyfikatorem wirtualnym (z resztą z perspektywy cooperatesWithDef co ciekawe).

Dlatego proponuję co nastepuję.
Operator niealgebraiczny działający na wirtualnym identyfikatorze pointera powinien zachować się jak w przypadku zwykłego obiektu pointerowego. Potraktować seed jako referencję do obiektu wskazywanego, pobrać jego nazwę i na ENVS wrzucić binder o tej nazwie i o wartości będącej identyfikatorem.

Cały czas pozostaje nierozwiązany problem aktualizacji wirtualnego pointera.
Code:
ITHeadhunter . cooperatesWith = ref(Freelancer where name = "Poe")

Ja wiem Haniu, że w tym przykładzie to nie bardzo ma sens, ale chcę tylko zobrazować tę kwestię i poddać ją pod dyskusję.

Standardowo przy aktualizacji wirtualnego obiektu na ENVS mamy nested(seed) (oraz seed'ów nadperspektyw) i zapis aktywacyjny procedury aktualizacyjnej. Dla tego przykładu nested(seed) wrzuci wnętrze obiektu Freelancer. Seed nie był binderem, więc nie mamy do niego dostępu w procedurze aktualizacyjnej. Oczywiście semantyka aktualizacji wirtualnego pointera może nie wymagać seed'a. Ale chyba nie można tego zakładać. Oczywiście jak napisała Hania seed może być również binderem do referencji, wtedy mamy do niego dostęp w procedurze aktualizacyjnej.
Zapraszam do dyskusji. I jak zwykle prostowania moich myśli :). Szczególnie Ciebie Haniu...


radamus
Posted: Saturday, February 26, 2005 7:34:00 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
I jeszcze jedna sprawa.
Załóżmy, że definiujemy perpektywę, która definiuje wirtualny pointer mający swój odpowiednik w składzie (w overloading views jest to naturalne).

Code:
create class EmpC
{
  instance Emp;
  name:string;
  salary:integer;
  worksIn: ref Dept;
}

create view RichEmpDef
{
   virtual objects RichEmp {return (Emp where salary > 3000) as e; }
   
   create view NameDef
   {
      virtual objects name {return e.name as n; }   
      on_retrieve {...}
      on_update(newName) {...}
   }
   
   create view SalaryDef
   {
      virtual objects salary {return e.salary as s;}
      on_retrieve {...}
      on_update(newSalary) {...}

   }

   create view WorksInDef
   {
      virtual objects worksIn as pointer {return ref(e.worksIn.Dept);}
      on_retrieve {...}
      on_update(newDeptReference) {...}

   }
}


Dla zwykłych podobiektów wirtualnych sack'i zwracają bindery z referencjami do odpowiednich podbiektów rzeczywistego obiektu Emp. Tak na prawdę można się (w tym konkretnym przykładzie) obejść bez tych definicji.
Po pierwsze ilość pod-obiektów name czy salary jest determinowana przez seed obiektu RichEmp. Po drugie Procedury aktualizacyjne podperspektyw mają dostęp do seed'a nadperspektywy, więc można napisać on_update dla salary tak:

Code:
on_update(newSalary) {e.salary = newSalary;}

zamiast
Code:
on_update(newSalary) {s = newSalary;}


A jednak w przykładach, które widziałem zawsze piszę się virtual objects dla podperspektywy. Nie twierdzę, że ta procedura jest niepotrzebna bo można łatwo podać wiele przykładów gdzie liczba podobiektów niekoniecznie jest wyznaczana przez seed nadperspektywy.
Teraz pointer:
Dlaczego definiując seed wirtualnego pointera programista musi zachowywać się inaczej. Nie może zwrócić bindera do rzeczywistego podobiektu pointerowego worksIn tylko musi w virtual objects zwrócić referencję do wskazywanego obiektu?
W on_update i tak będzie musiał skorzystać z seed'a nadperspektywy, żeby zaktualizować pointer.

Code:
on_update(newDeptReference) {e.WorksIn = newDeptReference;}


Ja nie twierdzę, że to jest źle. Tylko dla mnie jest pewna nienaturalność. Może dlatego nasunął mi się pomysł z osobną procedurą point_to. Zaczynałem o tym myśleć na przypadku overloadnig views, gdzie zawsze jest coś pod spodem co przykrywamy na zasadzie 1:1. Postępowałem zgodnie z, wydawało mi się regułą: virtual objects wyznacza seed obiektu wirtualnego (w tym wypadku jest to obiekt pointerowy) a to na co pokazuje ten obiekt określamy osobno. Bo wydawało mi się nienaturalne powiedzienie, że wirtualnym obiektem (virtual objects) jest referencja do wskazywanego obiektu. Wirtualnym obiektem (virtual objects) jest pointer a on wskazuje (point_to) na inny obiekt.
Mam nadzieję, że wyjaśniłem skąd w mojej głowie zrodził się pomysł point_to :)
Hanka
Posted: Saturday, February 26, 2005 11:23:09 AM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
radamus wrote:

[...]

Code:
delete ITHeadhunter . cooperatesWith . Freelancer


nie zadziała bo mamy do czynienia z identyfikatorem wirtualnym (z resztą z perspektywy cooperatesWithDef co ciekawe).




Cóż tym przykładem przekonałeś mnie, że faktycznie coś jeszcze jest nie tak z tym pointerami (można się oczywiście spierać, że procedura on_delete może wywołać po prostu usunięcie danego obiektu, ale to faktycznie jest trochę bez sensu). Dlatego trzeba kolejnych zmian np. takich jak poniżej proponujesz.

radamus wrote:


Dlatego proponuję co nastepuję.
Operator niealgebraiczny działający na wirtualnym identyfikatorze pointera powinien zachować się jak w przypadku zwykłego obiektu pointerowego. Potraktować seed jako referencję do obiektu wskazywanego, pobrać jego nazwę i na ENVS wrzucić binder o tej nazwie i o wartości będącej identyfikatorem.

Cały czas pozostaje nierozwiązany problem aktualizacji wirtualnego pointera.
Code:
ITHeadhunter . cooperatesWith = ref(Freelancer where name = "Poe")

Ja wiem Haniu, że w tym przykładzie to nie bardzo ma sens, ale chcę tylko zobrazować tę kwestię i poddać ją pod dyskusję.

Standardowo przy aktualizacji wirtualnego obiektu na ENVS mamy nested(seed) (oraz seed'ów nadperspektyw) i zapis aktywacyjny procedury aktualizacyjnej. Dla tego przykładu nested(seed) wrzuci wnętrze obiektu Freelancer. Seed nie był binderem, więc nie mamy do niego dostępu w procedurze aktualizacyjnej. Oczywiście semantyka aktualizacji wirtualnego pointera może nie wymagać seed'a. Ale chyba nie można tego zakładać. Oczywiście jak napisała Hania seed może być również binderem do referencji, wtedy mamy do niego dostęp w procedurze aktualizacyjnej.



Ehh?... Teraz to ja z kolei czegoś chyba nie rozumiem. Jeśli użytkownik potrzebuje odwołać się do seed w jakiejś operacji to definiuje seed jako binder (dodając „as nazwa” w definicji sack), jeśli nie potrzebuje się odwoływać to seed nie musi być binderem.
Zastanawianie się co będzie jeśli programista napisze tak sack, że seed nie będzie binderem, a następnie będzie się chciał do seeda odwołać np. z procedury on_delete, wydaje mi się sztucznym problemem. Zakładamy, że programista wie co robi i potrafi przewidzieć rezultaty swoich działań m.in. wie jak zdefiniować sack, żeby potem móc potem korzystać z seedów.

Dopuszczenie sytuacji gdzie seed dla wirtualnego pointera nie będzie binderem wydaje mi się sensowne np w przypadku, gdy nie ma zdefiniowanej żadnej operacji dla danej perspektywy tzn. potrzebujemy perspektywy tylko po to, żeby stworzyć wirtualny pointer, przez który będzie się dalej nawigować. W takiej sytuacji zmuszanie programisty do zdefiniowania nazwy, która nigdy nie będzie używana wydaje mi się mało eleganckie.


radamus wrote:

create view RichEmpDef
{
virtual objects RichEmp {return (Emp where salary > 3000) as e; }

create view NameDef
{
virtual objects name {return e.name as n; }
on_retrieve {...}
on_update(newName) {...}
}

create view SalaryDef
{
virtual objects salary {return e.salary as s;}
on_retrieve {...}
on_update(newSalary) {...}

}

create view WorksInDef
{
virtual objects worksIn as pointer {return ref(e.worksIn.Dept);}
on_retrieve {...}
on_update(newDeptReference) {...}

}
}[/code]

Dla zwykłych podobiektów wirtualnych sack'i zwracają bindery z referencjami do odpowiednich podbiektów rzeczywistego obiektu Emp. Tak na prawdę można się (w tym konkretnym przykładzie) obejść bez tych definicji.
Po pierwsze ilość pod-obiektów name czy salary jest determinowana przez seed obiektu RichEmp. Po drugie Procedury aktualizacyjne podperspektyw mają dostęp do seed'a nadperspektywy.



Tak, ale jeśli napiszesz zapytanie EmpBoss.Salary to liczba obiektów zwróconych przez takie zapytanie jest zależna od liczby seedów generowanych przez podperspektywę SalaryDef. Czyli technicznie te definicje sack są bardzo potrzebne (nawet jeśli potem nie odwołujemy się do tych seedów). W szczególności jeśli definicja sack będzie pusta (nic nie zwróci), to nie zostanie wywołana żadna operacja na obiekcie wirtualnym generowanym przez ta perspektywę (bo nie mamy żadnego seeda => nie ma identyfikatorów wirtualnych => nie ma obiektów wirtualnych).


---

Może podsumuję to co zostało powiedziane w tym wątku (jeśli ktoś się, z którąś częścią nie zgadza to niech proszę o komentarz; tak samo jeśli o czymś istotnym zapomniałam):

1) Perspektywa definiująca wirtualny pointer jest rozróżniana od def. „zwykłej” perspektywy klauzulą „as pointer” w nagłówku definicji perspektywy. Jest to spowodowane tym, że identyfikatory wirtualne generowane taką perspektywę muszą być rozróżnialne od „zwykłych” identyfikatorów wirtualnych. Identyfikator wirtualny dla takiego obiektu ma postać:
<flag „I’m virtual pointer”, view def id, seed>

2) Wprowadzamy ograniczenie na to co może zwracać sack takiej perspektywy, tzn:

· Referencję do obiektu
· Binder z taką referencją

Tutaj możemy też przyjąć wersję Radka, że sack zwraca rzeczywisty pointer, lub binder z takim rzeczysistym pointerem. Wydaje mi się, że wybór między tymi wersjami nie będzie miał większego znaczenia (ale może się mylę...) - ważne jest jedynie dzialanie funkcji nested - poniżej.

3) Działanie funkcji nested( wirtualny pointer ):
· Jeśli seed jest referencją do obiektu to funkcja zwraca binder do obiektu wskazywanego
· Jeśli seed jest binderem z taką referencją to funkcja zwraca ten binder oraz binder do obiektu wskazywanego

(Oczywiście tutaj można jeszcze dodać bindery do podperspektyw jako rezultat funkcji nested; chociaż w tym momencie nie rozstrzygam czy to ma sens, żeby wirtualny pointer miał podperspektywy)

4) Perspektywy definiujące pointery mogą być aktualizowane

5) Rezygnujemy z wprowadzenia do definicji perspektywy definiującej pointer dodatkowych elementów takich jak „point_to” (czy tak?)

Radku, mam nadzieję, że to co napisałam powyżej jest zrozumiałe, ale już nie potrafię tego prościej napisać.

Proszę o komentarze. Może tu jeszcze potrzebne są kolejne zmiany.



stencel
Posted: Saturday, February 26, 2005 2:26:44 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Hanka wrote:
1) Perspektywa definiująca wirtualny pointer jest rozróżniana od def. „zwykłej” perspektywy klauzulą „as pointer” w nagłówku definicji perspektywy. Jest to spowodowane tym, że identyfikatory wirtualne generowane taką perspektywę muszą być rozróżnialne od „zwykłych” identyfikatorów wirtualnych. Identyfikator wirtualny dla takiego obiektu ma postać: <flag „I’m virtual pointer”, view def id, seed>


Ponizej w osobnym poscie sprobuje ponownie zaorać ten ugór i przedstawić całkiem na nowo te koncepcje. Tam beda rozroznienia ale trochę na innej zasadzie.

Hanka wrote:
2) Wprowadzamy ograniczenie na to co może zwracać sack takiej perspektywy, tzn: Referencję do obiektu, Binder z taką referencją


To nie jest dobre. Przypominam post Szefa, w ktorym pisal on o odwzorowywaniu relacyjnej bazy danych za pomocą perspektyw. W takiej sytuacji seed wirtualnego obiektu pointerowego jest wartoscia klucza obcego.

stencel
Posted: Saturday, February 26, 2005 2:32:38 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Radek ma jednak wiele racji. A ja wyciagne jeszcze dalsze wnioski z mojego scholatycznego przykladu, w ktorym deref(BigUniversity).address nie bylo rowne deref(BigUniversity.address).

Programista zrobil sobie w tym przykladzie krzywde, bo dalismy mu mozliwosc pomylki.

Teraz do analizy. Ab Iove principium. Programista pracujacy z obiektami materialnymi (rowniez administrator definiujacy perspektywy dla programistow aplikacyjnych) ma do czynienia z trzeba rodzajami obiektow w skladzie:

1. Materialne obiekty atomowe.
2. Materialne obiekty zlozone.
3. Materialne obiekty pointerowe.

Takoz powinno byc z obiektami wirtualnymi. Mamy wiec:

4. Wirtualne obiekty atomowe.
5. Wirtualne obiekty zlozone.
6. Wirtualne obiekty pointerowe.

Natomiast mechanizm definiowania perspektyw nie wprowadza takiego rozroznienia (dziwne!), choc chcemy by bylo przezroczyscie, czyli obiekty wirtualne maja takie same cechy jak materialne. Z braku tego rozroznienia biora sie np. problemy z deref dla wirtualnego obiektu zlozonego (deref(BigUniversity).address != deref(BigUniversity.address)). Pisalem o tym wczesniej i dyskusja naprowadzila mnie wlasnie na wnioski opisane w tym poscie.

Tak wiec, mamy trzy rodzaje definicji perspektyw definiujace odpowiednio obiekty typu 4, 5, 6 z powyzszej listy.

Perspektywa definiujaca wirtualne obiekty atomowe nie ma podperspektyw, ale może mieć funkcję deref.

Perspektywa definiujaca wirtualne obiekty złożone ma podperspektywy, ale nie może mieć funkcji deref. To nam rozwiązuje "scholastyczny" problem z derefem na obiektach złożonych.

Wykonanie deref na wirtualnym obiekcie złożonym powoduje wywołanie deref na wszystkich podperspektywach, na których można wykonać deref i skonstruowanie struktury binderów z wyników tych derefów i nazw obiektow wirtualnych podperspektyw. W przykładzie:

Code:
create view BigUniversityDef {
  virtual objects BigUniversity { return (University where graduateNumber > 10000) as bu; }
 
  create view NameDef {
    virtual objects name { return bu.name as n; }
    on_retrieve {
      return deref(n);
    }
  }

  create view AddressDef {
    virtual objects address { return bu.address as a; }
    on_retrieve {
      return deref(a);
    }
  }

}


Weźmy teraz jakis obiekt wirtualny BigUniversity i wykonajmy na nim deref. To oznacza, że deref jest wykonywane na obu podperspektywach. Przypuśćmy, że te operacje zwracają odpowiednio "PJIIT" i "Warsaw". Wowczas wynikiem deref na naszym obiekcie BigUniversity jest:

Code:
struct{ name("PJIIT"), address("Warsaw")  }


Jak widać dzięki temu unikamy opisywanego wcześniej scholastycznego problemu z derefami. Oczywiście jesli jakaś podperspektywa nie pozwala na wykonanie deref to odpowiedni binder nie znajdzie się w wynikowej strukturze..

Perspektywa definiujaca wirtualne obiekty pointerowe nie ma podperspektyw ani funkcji deref. Ma za to funkcję points_to (ukłony dla Radka), która jest wywoływana w chwili, gdy chcemy wyłuskać obiekt wskazywany przez nasz wirtualny obiekt pointerowy, np. przy wywołaniu operatora niealgebraicznego.

Moim zdaniem to się trzyma kupy. Mamy rozroznienie obiektow materialnych ale takie samo rozroznienie dotyczy obiektow wirtualnych.
Hanka
Posted: Saturday, February 26, 2005 3:13:11 PM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
Być może nie zostało to nigdzie formalnie napisane, ale przecież istnieje już rozróżnienie obiektów wirtualnych na: proste (czyli definiowane przez perspektywę bez podperspektyw), złożone (zagnieżdżone perspektywy) i pointerowe (z klauzula „as pointer” w nagłówku). Ale może faktycznie należało to podkreślić.

Bardzo podoba mi się Twój pomysł na zrobienie deref dla obiektu złożonego (choć nie do końca widzę związek z tematem pointerów wirtualnych :) ). Ale tego faktycznie trochę do tej pory brakowało.

Natomiast cały czas nie widzę konieczności wprowadzenia points_to i pozostawienia sekcji „virtual objects”. Być może konkretny przykład gdzie takie rozróżnienie jest konieczne by pomógł w dyskusji (po dotychczasowych przykładach nie jestem przekonana czy jeśli zdefiniujemy points_to to jeszcze potrzebujemy informacji zawartych w sekcji "virtual objects", czyli czy tego co chcesz zawrzeć w points_to nie można po prostu umieścić w sekcji „virtual objects”).
Poza tym z jednej strony piszesz, że ograniczenie na wartości zwracane przez procedurę „virtual objects” dla wirtualnego pointera nie jest dobre, a z drugiej strony chcesz wprowadzić sekcje point_to gdzie podobne ograniczenie musi być narzucone (tzn. point_to musi wskazywać na obiekt, do którego prowadzi pointer)...

Hanka
Posted: Saturday, February 26, 2005 3:26:32 PM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
stencel wrote:

Perspektywa definiujaca wirtualne obiekty pointerowe nie ma podperspektyw ani funkcji deref. Ma za to funkcję points_to (ukłony dla Radka), która jest wywoływana w chwili, gdy chcemy wyłuskać obiekt wskazywany przez nasz wirtualny obiekt pointerowy, np. przy wywołaniu operatora niealgebraicznego.


Jeszcze szczegół: wydaje mi się że jeśli zdefiniujemy takie deref jak opisałeś dla obiektów złożonych to perspektywa definiujaca wirtualne obiekty pointerowe musi mieć jednak zaimplementowane deref.
radamus
Posted: Saturday, February 26, 2005 3:45:08 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
A ja dorzucę jeszcze jeden kamyczek.

Hanka wrote:

(...)W szczególności jeśli definicja sack będzie pusta (nic nie zwróci), to nie zostanie wywołana żadna operacja na obiekcie wirtualnym generowanym przez ta perspektywę (bo nie mamy żadnego seeda => nie ma identyfikatorów wirtualnych => nie ma obiektów wirtualnych).


W książce profesora jest przykład perspektywy ze stanem (pp 388-389). Dotyczacej przeglądu pracownika. Jedna z podperspektyw jest zdefiniowana nastepująco.
Code:
create view PracPrzeglądDef {
//...

     create view AdnotacjaDef {
            virtual objects Adnotacja{ return (PracPrzeglądDef.Adn where p = (dotyczy.Prac)) as a; }
            on_retrieve do { return if exists( a ) then deref( a.tekst ) else "";};
            on_update ( nowyTekst ) do {if exists( a ) then a.text := nowyTekst;
                                           else { create (ref p as dotyczy, nowyText as tekst) as Adn;
                                                       PracPrzeglądDef :< Adn; }
                                                      }
       }


//...
}



Jeżeli pracownik nie ma jeszcze adnotacji to seed'a nie ma. Co z resztą jest wykorzystywane procedurach aktualizacyjnych.

Możemy potem adnotację wpisać zapytaniem:
Code:
(PracPrzegląd where Nazwisko = ”Nowak”). Adnotacja := ”Wzorowy - nagrodzić”;


Ten przykład pokazuje coś innego:
definicja sack nic nie zwraca => nie mamy żadnego seeda => jest identyfikator wirtualny => jest obiekt wirtualny => możemy aktualizować



Hanka
Posted: Saturday, February 26, 2005 4:14:47 PM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
radamus wrote:
A ja dorzucę jeszcze jeden kamyczek.

Hanka wrote:

(...)W szczególności jeśli definicja sack będzie pusta (nic nie zwróci), to nie zostanie wywołana żadna operacja na obiekcie wirtualnym generowanym przez ta perspektywę (bo nie mamy żadnego seeda => nie ma identyfikatorów wirtualnych => nie ma obiektów wirtualnych).


W książce profesora jest przykład perspektywy ze stanem (pp 388-389). Dotyczacej przeglądu pracownika. Jedna z podperspektyw jest zdefiniowana nastepująco.
Code:
create view PracPrzeglądDef {
//...

     create view AdnotacjaDef {
            virtual objects Adnotacja{ return (PracPrzeglądDef.Adn where p = (dotyczy.Prac)) as a; }
            on_retrieve do { return if exists( a ) then deref( a.tekst ) else "";};
            on_update ( nowyTekst ) do {if exists( a ) then a.text := nowyTekst;
                                           else { create (ref p as dotyczy, nowyText as tekst) as Adn;
                                                       PracPrzeglądDef :< Adn; }
                                                      }
       }


//...
}



Jeżeli pracownik nie ma jeszcze adnotacji to seed'a nie ma. Co z resztą jest wykorzystywane procedurach aktualizacyjnych.

Możemy potem adnotację wpisać zapytaniem:
Code:
(PracPrzegląd where Nazwisko = ”Nowak”). Adnotacja := ”Wzorowy - nagrodzić”;


Ten przykład pokazuje coś innego:
definicja sack nic nie zwraca => nie mamy żadnego seeda => jest identyfikator wirtualny => jest obiekt wirtualny => możemy aktualizować






Zaraz, zaraz! To coś mi się tutaj nie zgadza. Przecież relacja seed - identyfikator wirtualny jest 1:1, więc sytuacja gdy nie ma seed, a jest identyfikator wirtualny jest chyba niemożliwa.
Identyfikatory wirtualne powstają w wyniku "opakowywania" seedów w postać: <flag "I'm virtual, view def id, seed> (1 seed = 1 identyfikator wirtualny)

Oczywiście operacja on_update wywoła się jedynie gdy mamy identyfikator wirtualny.

Niech mnie ktoś poprawi jeśli źle coś piszę, bo może mam jakieś zaćmienie.

stencel
Posted: Saturday, February 26, 2005 4:33:56 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Hanka wrote:
Natomiast cały czas nie widzę konieczności wprowadzenia points_to i pozostawienia sekcji „virtual objects”. Być może konkretny przykład gdzie takie rozróżnienie jest konieczne by pomógł w dyskusji.


Wydaje mi sie, ze taka sytuacja wystepuje np. przy odwzorowaniu zawartosci relacyjnej bazy danych. Seedami sa wowczas wartosci kluczy obcych. A points_to generuje obiekt, ktory ma byc zwrocony w chwili wywolania nested. Seed zawiera wiec wartosc z relacyjnej bazy danych, a points_to daje wirtualny pointer. Oczywiscie mozna sprobowac to skleic w jedno, ale na obecna chwile mi to nie lezy. Chce miec oddzielony seed od docelowo generowanego wirtualnego pointera.

Hanka wrote:
Poza tym z jednej strony piszesz, że ograniczenie na wartości zwracane przez procedurę „virtual objects” dla wirtualnego pointera nie jest dobre, a z drugiej strony chcesz wprowadzić sekcje point_to gdzie podobne ograniczenie musi być narzucone (tzn. point_to musi wskazywać na obiekt, do którego prowadzi pointer)...


Tak, bo inne jest przeznaczenie obydwu klauzul. Pierwsza po prostu identyfikuje pojedynczy wirtualny pointer, a druga wskazuje obiekt wskazywany. Analogie moge podac do materialnych obiektow pointerowych:

<i1, name, i2>

i1 to identyfikator obiektu pointerowego, i2 to identyfikator obiektu wskazywanego. Tak samo w wypadku pointera wirtualnego.
virtual object definiuje jego tozsamosc (odpowiada i1), a points_to definiuje obiekt wskazywany (odpowiada i2).

Hanka wrote:
Jeszcze szczegół: wydaje mi się że jeśli zdefiniujemy takie deref jak opisałeś dla obiektów złożonych to perspektywa definiujaca wirtualne obiekty pointerowe musi mieć jednak zaimplementowane deref.


To wymaga wiec uzupelnienia. Points_to odpowiada on_retrieve wirtualnych obiektow atomowych. W wypdku liczenia deref dla wirtualnego obiektu zlozonego, uzywamy deref dla podperspektyw atomowych i points_to dla podperspektyw pointerowych.

radamus
Posted: Saturday, February 26, 2005 6:43:55 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Trochę sie nam mieszają posty, chyba za dużo rzeczy na raz...
Hanka wrote:

(...) Natomiast cały czas nie widzę konieczności wprowadzenia points_to i pozostawienia sekcji „virtual objects”.

Być może konkretny przykład gdzie takie rozróżnienie jest konieczne by pomógł w dyskusji (po dotychczasowych przykładach nie jestem przekonana czy jeśli zdefiniujemy points_to to jeszcze potrzebujemy informacji zawartych w sekcji "virtual objects", czyli czy tego co chcesz zawrzeć w points_to nie można po prostu umieścić w sekcji „virtual objects”).


Ja nie wiem do końca czy ten przykład jest TYM przykładem. W razie czego wyprowadźcie mnie z błędu.

Code:
class University
{
  name:string;
  address:string;
  graduateNumber:integer;
  attendees[0..*]:ref Student;

}


create view BigUniversityDef {
  virtual objects BigUniversity { return (University where graduateNumber > 10000) as bu; }
 
  create view NameDef {
    virtual objects name { return bu.name as n; }
    on_retrieve {
      return deref(n);
    }
  }

  create view AddressDef {
    virtual objects address { return bu.address as a; }
    on_retrieve {
      return deref(a);
    }
  }

  create view BestAttendeesDef{
   virtual objects bestAttendees {return (bu.attendees where Student.avgGrade > 4.5) as at;}
   points_to Student {return at.Student;}
   on_delete {delete at;}
}

}



Przykład zapytania. Usuń z BigUniversity pointer prowadzący do studenta o imieniu Poe.

delete (BigUniersity where name == "PW").bestAttendees where Student.name == "Poe";


Utworzyłem seed, który jest binderem z referencją do obiektu pointerowego a nie do tego co na co wskazuje pointer. Oczywiście można tak zmodyfikować funkcję nested aby i z tym sobie poradziła. Dotychczas Hania zakładała, że wartością może być referencja do wskazywanego obiektu lub binder z tą referencją. Teraz trzeba byłoby jeszcze dorzucić, że może to również być referencja do obiektu pointerowego. Ale myśle, że i to nie wystarczy. Bo przecież, teraz na to wpadłem, taki obiekt na który wskazuje pointer może być przykryty np. przeciążającą perpektywą i możemy mieć wirtualny identyfikator. Zaczyna mi się wydawać, że tak jak pisał Krzysiek nie można dać takiego ograniczenia na wartości zwracane przez sack wirtualnego pointera.
stencel
Posted: Saturday, February 26, 2005 8:16:00 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
Ja nie wiem do końca czy ten przykład jest TYM przykładem. W razie czego wyprowadźcie mnie z błędu.


Tak. Super. Ten przyklad oddaje dokladnie to, co opisalem. Uwazam, ze tak powinnismy podejsc do perspektyw w SBA.

Dixi.
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Main Forum RSS : RSS

Powered by Yet Another Forum.net version 1.9.1.6 (NET v2.0) - 11/14/2007
Copyright © 2003-2006 Yet Another Forum.net. All rights reserved.
This page was generated in 0.266 seconds.