Welcome Guest Search | Active Topics | Members | Log In

Identyfikatory wirtualne a przechowywanie referencji Options · View
Hanka
Posted: Sunday, February 27, 2005 9:07:03 AM
Rank: Member

Joined: 12/7/2004
Posts: 14
Points: 0
Teraz to fajnie wygląda. I to nie dlatego, że został podany TEN przykład, ale została przedstawiona trochę inna koncepcja niż wcześniej. W przykładzie point_to odwołuje się do seedów, co wydaje mi się fajniejszym rozwiązaniem niż wcześniejsze (nie mamy zdublowanych informacji w point_to i virtual_objects, ani jakiś dziwnych bagów zwracanych przez sack, co było imho wadą początkowych propozycji).

Natomiast to co mnie jeszcze zastanawia, to czy nie będzie tak, że w ogólnym przypadku sack wirtualnego pointera musi zwracać binder z referencją do obiektu pointerowego tego pointera na końcu ścieżki nawigacyjnej. Na przykład jeśli wprowadzamy wirtualny pointer z A do X, który jest zdefiniowany wyrażeniem A.m.B.g.G.k.X to seed takiego pointera wirtualnego będzie binderem z referencją do obiektu pointerowego k. Przecież seed musi jednoznacznie identyfikować obiekt wirtualny, a dodatkowo liczba pointerów wirtualnych powinna w tym przykładzie wynosić count(A.m.B.g.G.k). Natomiast w takiej sytuacji point_to będzie się sprowadzać do { return nazwaSeed . obiektWskazywany; }
(Oczywiście nie będzie to prawdą gdy odwzorowanie jakiegoś elementu ścieżki A.m.B.g.G w k jest 1:1, ale to jest szczególny przypadek.)


radamus wrote:


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.


Formalne wprowadzenie takiego ograniczenia miało sens gdy był problem co zwrócić przez nested( wirtualny ob. pointerowy). Teraz wynik tej funkcji jest określony przez point_to.
radamus
Posted: Sunday, February 27, 2005 11:28:30 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Hanka wrote:
Teraz to fajnie wygląda. I to nie dlatego, że został podany TEN przykład, ale została przedstawiona trochę inna koncepcja niż wcześniej. W przykładzie point_to odwołuje się do seedów, co wydaje mi się fajniejszym rozwiązaniem niż wcześniejsze (nie mamy zdublowanych informacji w point_to i virtual_objects, ani jakiś dziwnych bagów zwracanych przez sack, co było imho wadą początkowych propozycji).

Początkowe propozycje mają zazwyczaj wady :). Chodziło mi dokładnie o to co Krzyśkowi udało się sformułować. Tak to miałem z resztą zaimplementowane. Ale przykład z bagiem był faktycznie nietrafiony...

Hanka wrote:

Natomiast to co mnie jeszcze zastanawia, to czy nie będzie tak, że w ogólnym przypadku sack wirtualnego pointera musi zwracać binder z referencją do obiektu pointerowego tego pointera na końcu ścieżki nawigacyjnej.

W ogólny przypadku to chyba nie bo przecież wirtualny pointer może być zupełnie wirtualny, to znaczy nie istnieje żaden pointera, którego referencję zapakowaną w binder zwracamy w sacku. Patrz podnoszony tu temat wirtualnych pointerów przykrywających związaki klucz główny -> klucz obcy w relacyjnej bazie danych.
Temat niewątpliwie rozwojowy.


Hanka
Posted: Sunday, February 27, 2005 11:59:33 AM
Rank: Member

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

W ogólny przypadku to chyba nie bo przecież wirtualny pointer może być zupełnie wirtualny, to znaczy nie istnieje żaden pointera, którego referencję zapakowaną w binder zwracamy w sacku. Patrz podnoszony tu temat wirtualnych pointerów przykrywających związaki klucz główny -> klucz obcy w relacyjnej bazie danych.


Racja. Zapomniałam o modelu relacyjnym.
radamus
Posted: Sunday, February 27, 2005 12:44:31 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Hanka wrote:
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.



Odkryłem to jeszcze na SOFSEM'ie kiedy ćwiczyłem mój prototyp na przykładach z książki. Ale do naszej dyskusji nie bardzo zdawałem sobię sprawę z problemu. Przykład jest pragmatyczny, więc dlaczego nie mogłoby tak być? Dlatego moja implementacja pozwala na taką sytuację.
Ja już rozumiem (podziękowania dla Hani za jasne i cierpliwe wyjaśnienia :-))) ), że ilość ziaren zwracanych przez virtual objects określa ilość obiektów wirtualnych. Tutaj mamy sytuację w której ziarna nie ma. Nie ma więc żadnego obiektu wirtualnego. Jednak wirtualny identyfikator jest, bo z jakichś powodów może to być pragmatycznie wygodne (patrz przykład). Od tego czy ziarno jest czy go nie ma może zależeć czy wykonamy jakąś operację czy nie.
Bo nawet jesli w poniższym przykładzie nie będzie studentów, którzy mają średnią powyżej 4.5 i ucza się na dużej uczelni:

Code:
create view BigUniversityDef {
  virtual objects BigUniversity { return (University where graduateNumber > 10000) as bu; }
 
//...
  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;}
}
//...
}


To można by napisać zapytanie:

Code:
(BigUniversity where name == "PJWSTK").bestAttendees.Student.name;


Wynik będzie pusty.

Ale podstawienie na pointer może mieć sens:
Code:
(BigUniversity where name == "PJWSTK").bestAttendees = ref(Student where name == "Poe");

Można przecież zdefiniować...

Code:
create view BestAttendeesDef{
   virtual objects bestAttendees {return (bu.attendees where Student.avgGrade > 4.5) as at;}
   points_to Student {return at.Student;}
   on_update (newStudentRef)
   {
        if( newStudentRef.avgGrade > 4.5 )
       {
            if(exist(at))
           {
               if( for all(at) (Student.ID != newStudentRef.ID) )
                    bu :<  create (ref(newStudentRef) as attendees); //to ref chyba jest tu niepotrzebne
                                                                                         //bo przy podstawieniu na pointer jest ref
               else {//taki student już istnieje nic nie rób}
           }else { //nie było dotychczas bestAttendees
                       bu :<  create (ref(newStudentRef) as attendees);
                    }
        }else {//student ma za niską średnią}
  }
}


Mam nadzieję, że dobrze to napisałem bo nie sprawdziłem tego w YAOD'zie.


Poproszę o kontrprzykład w którym taki wirtualny identyfikator bez seeda powodowałoby ewidentny błąd.
Hanka
Posted: Sunday, February 27, 2005 1:08:38 PM
Rank: Member

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


[...]
To można by napisać zapytanie:

Code:
(BigUniversity where name == "PJWSTK").bestAttendees.Student.name;


Wynik będzie pusty.


Ale podstawienie na pointer może mieć sens:
Code:
(BigUniversity where name == "PJWSTK").bestAttendees = ref(Student where name == "Poe");





Zamiast podać kontrprzykład przedstawię modyfikację przykładu, która nie będzie burzyła zależności mówiącej, że identyfikator wirtualny jest zbudowany na bazie seed. (W przykładzie dla prostoty zakładam, ze nie mamy typów)

Code:

create view BestAttendeesDef{
   virtual objects bestAttendees {
          if exists(bu.attendees where Student.avgGrade > 4.5) return (bu.attendees where Student.avgGrade > 4.5) as at;
          else return "abc" as at;
   }
   points_to Student {return at.Student;}
   on_insert (newStudentRef) do
   {
        if( at equals „abc” ) { … }
        else { … }
   }
}


W ten sposób wilk syty i owca cała. Ty możesz przeprowadzić swoją aktualizaję, a mechanizm nie musi być modyfikowany.
stencel
Posted: Sunday, February 27, 2005 2:55:24 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Cos mi te Wasze przyklady nie leżą.

Radek:

Code:
create view BestAttendeesDef{
   virtual objects bestAttendees {return (bu.attendees where Student.avgGrade > 4.5) as at;}
   points_to Student {return at.Student;}
   on_update (newStudentRef)
   {
        if( newStudentRef.avgGrade > 4.5 )
       {
            if(exist(at))
           {
...


Po co pytac o exists(at)? Przeciez on_update jest wykonywane na istniejacym jednym obiekcie wirtualnym, wiec wiadomo, ze on istnieje. Jesli go nie ma, to nie mozna wykonac update!

Hanka:

Code:
create view BestAttendeesDef{
   virtual objects bestAttendees {
          if exists(bu.attendees where Student.avgGrade > 4.5) return (bu.attendees where Student.avgGrade > 4.5) as at;
          else return "abc" as at;
   }
   points_to Student {return at.Student;}
   on_insert (newStudentRef) do
   {
        if( at equals „abc” ) { … }
        else { … }
   }
}


Wykonanie on_insert na wirtualnym pointerze nie ma sensu (podobnie jak na materialnym). Raczej chodzilo Ci Hanka o on_new (czy on_create)?

W ogole wydaje mi sie, ze ten przypadek jest rozwiazywalny tylko poprzez on_insert na perspektywie BigUniversityDef (wtedy ma sens pytanie o exists(bestAttendees)) albo poprzez on_new na perspektywie BestAttendeesDef.
Hanka
Posted: Sunday, February 27, 2005 3:29:42 PM
Rank: Member

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


Wykonanie on_insert na wirtualnym pointerze nie ma sensu (podobnie jak na materialnym). Raczej chodzilo Ci Hanka o on_new (czy on_create)?



Mi nie chodziło o konkretny przykład, tylko o zaproponowanie sztuczki co można zrobić, żeby wykonać operację gdy perspektywa normalnie nie zwraca obiektu wirtualnego (bez wnikania w logikę operacji i zastanawiania się czy to ma sens czy nie). Po prostu nie podobało mi się (i nie podoba) rozwiązanie gdy wprowadza się identyfikator wirtualny bez seeda. Faktycznie on_insert dla pointera nie ma sensu - źle przepisałam z przykładu Radka - tu powinno być on_update z przykładu Radka (oczywiście bez wnikania w logikę tej operacji).
stencel
Posted: Sunday, February 27, 2005 3:42:36 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Hanka wrote:
Mi nie chodziło o konkretny przykład, tylko o zaproponowanie sztuczki co można zrobić, żeby wykonać operację gdy perspektywa normalnie nie zwraca obiektu wirtualnego (bez wnikania w logikę operacji i zastanawiania się czy to ma sens czy nie). Po prostu nie podobało mi się (i nie podoba) rozwiązanie gdy wprowadza się identyfikator wirtualny bez seeda.


Tu sie zgadzam. Nie ma obiektu wirtualnego bez seeda. Najwyzej seed jest sztuczny, jak w Twoim przykladzie.

Radku. Zgódź się z tym. Zaleznosc 1:1 seed <-> obiekt wirtualny naprawde ma sens. A jak widac mozna ją w razie czego obejść, co pokazała Hanka.
radamus
Posted: Sunday, February 27, 2005 5:50:35 PM

Rank: Advanced Member

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

Radku. Zgódź się z tym. Zaleznosc 1:1 seed <-> obiekt wirtualny naprawde ma sens. A jak widac mozna ją w razie czego obejść, co pokazała Hanka.


Ja się zgadzam z tym, że liczba ziaren wyznacza liczbę obiektów wirtualnych (to naprawdę ma sens!). Zastanawiałem się tylko czy odstępstwo od tej reguły przy wartości zero spowoduje jakieś problemy. Na razie nie znalazłem przykładu, który by mi jasno powiedział, że tak jest. Skoro nie znalazłem a widzę przykłady pokazujące możliwość wykorzystania takiej możliwości to zaczynam się głośno zastanawiać. Taką mam naturę. Ale dzięki temu mogę usłyszeć wasze głosy w tej kwestii. I dlatego jeszcze trochę was pomęczę (jak przesadzam to mi to powiedzcie). Uważam po prostu, że reguły są dla ludzi a nie ludzie dla reguł...


Code:
class Emp{

name: string;
address[0..1] : string;
dailyWorkHours : integer;

//..

}

create view LazyEmpDef {
                    virtual objects LazyEmp { return (Emp where dailyWorkHours < 4) as e; }
 
     create view AddressDef {
                          virtual objects address {  return e.address as a; }
                          on_update (newAddress) {if( exist(a) )  a = newAddress;
                                                                 else e :< create (newAddress as address);}                   
      }
}


Oczywiście mogę napisać:
Code:
   create view AddressDef {
                          virtual objects address {  if ( exist(e.address) ) return e.address as a;
                                                                else return "coś tam" as a; }
                          on_update (newAddress) { if( a != "coś tam" )  a = newAddress;
                                                                  else e :< create (newAddress as address); }                   
}


Tylko czy zawsze znajdę odpowiednie "coś tam"?


To jest oczywiście problem z danymi opcjonalnymi. Może on być w tym wypadku rozwiązany inaczej. Tak jak proponuje Krzysiek procedurą on_insert na poziomie LazyEmpDef czyli:

Code:
create view LazyEmpDef {
                    virtual objects LazyEmp { return (Emp where dailyWorkHours < 4) as e; }
                     on_insert(new newAddress) {if(exist e.address) a = address; //?? ale to mi nie pasuje - raczej chyba błąd
                                                          else e :<  newAddress as address;}

                    virtual objects address {  return e.address as a;  }
                          on_update(newAddress) {  a = newAddress; }
                  }


a resztę zostawić w rękach użytkownika perspektywy.

Code:
if( exist( (LazyEmp where name = "Poe").address) )  (LazyEmp where name = "Poe").address = "12 avenue";
else (LazyEmp where name = "Poe") :< create ("12 avenue" as address);


Tylko ile razy będzie on to musiał w kodzie umieścić?
A tak mógłby spokojnie napisać:
Code:
(LazyEmp where name = "Poe").address = "12 avenue";

i nie martwić się o nic.



stencel
Posted: Sunday, February 27, 2005 6:24:53 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Code:
create view LazyEmpDef {
                    virtual objects LazyEmp { return (Emp where dailyWorkHours < 4) as e; }
 
     create view AddressDef {
                          virtual objects address {  return e.address as a; }
                          on_update (newAddress) {if( exist(a) )  a = newAddress;
                                                                 else e :< create (newAddress as address);}                   
      }
}

To exist(a) jest straszna herezja. Juz sie wybieram do Lodzi zeby sklecic z drewek zgrabny stosik. W tym kontekscie ten warunek zawsze ma wartosc true. Bo on_update jest wywolywane na istniejacym obiekcie wirtualnym.

Code:
create view AddressDef {
   virtual objects address {  if ( exist(e.address) ) return e.address as a;
                                        else return "coś tam" as a; }
   on_update (newAddress) { if( a != "coś tam" )  a = newAddress;
                                           else e :< create (newAddress as address); }                   
}

To już wyglada niezle. Gdyby przyjrzec sie analogicznym obiektom materialnym (a dla zdrowia warto), to takie "abc" jest po prostu wartoscia domyslna wymaganego podobiektu. Nic wiec nadzwyczajnego sie tu nie dzieje. Zawsze wiec znajdzie sie odpowiednie cos tam, poniewaz z Twojego przykladu wynika, ze chcialbys zeby address byl wymaganym podobiektem. Musisz mu wiec zapewnic wartosc domyslna, albo miec zalozenie ze wszystkie materialne obiekty bazowe maja adresy. Wtedy problem znika.

Code:
create view LazyEmpDef {
                    virtual objects LazyEmp { return (Emp where dailyWorkHours < 4) as e; }
                     on_insert(new newAddress) {if(exist e.address) a = address; //?? ale to mi nie pasuje - raczej chyba błąd
                                                          else e :<  newAddress as address;}
                  }

A po co takie dziwo? Jak juz adress jest, to po go ponownie wstawiac? Mozna:

Code:
on_insert(new newAddress) {if(not exist(e.address)) e :<  newAddress as address;}




Rozwazmy teraz Twoj ostatni przyklad:

Code:
(LazyEmp where name = "Poe").address = "12 avenue";

Niech LazyEmp bedzie obiektem materialnym z opcjonalnym (skoro moze go nie byc) atrybutem address.
Wtedy taka instrukcja jest niepoprawna i trzeba zastosowac to, co Ci sie tak nie podoba (ale krocej), czyli:

Code:
if( exist( ((LazyEmp where name = "Poe") as e).address) )  e.address = "12 avenue";
else e :< create ("12 avenue" as address);

Poza tym taki kod mozna umiescic w metodzie setAdress i juz tylko ta metoa sie poslugiwac. Programista napisze wiec:

Code:
(LazyEmp where name = "Poe").setAddress("12 avenue");


Tak jest w wypadku obiektow materialnych. Dlaczego wiec mialoby byc inaczej dla obiektow wirtualnych?

Rozwiazaniem moga byc tez wartosci domyslne, ktore w wypadku obiektow wirtualnych przybieraja postac takiej "lewej" wartosci seedu.
radamus
Posted: Sunday, February 27, 2005 8:30:45 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Przekonałeś mnie. Bedę pamiętał, żeby zawsze najpierw dla zdrowia przyjrzeć się analogicznym obiektom materialnym. A jak przyjadę do Warszawy to przywiozę Ci zapałki :)

Czyli:
Jeżeli w rzeczywistym obiekcie atrybut jest opcjonalny. A my w perspektywie chcemy, żeby odpowiadający wirtualny nie był opcjonalny. To znaczy był widziany jako nieopcjonalny. Innymi słowy, aby zapytanie

Code:
(LazyEmp where name = "Poe").address = "12 avenue";


było poprawne. Musimy mieć jakąś wartość domyślną. Tylko nie wiem czy sama wartość domyślna wystarczy. Bo przecież atrybut opcjonalny może istnieć i być ustawiony na tę wartość domyślną. Wtedy dla definicji:

Code:
create view AddressDef {
   virtual objects address {  if ( exist(e.address) ) return e.address as a;
                                        else return "coś tam" as a; }
   on_update (newAddress) { if( a != "coś tam" )  a = newAddress;
                                           else e :< create (newAddress as address); }                   
}


możemy utworzyć obiekt address nawet wtedy gdy już istnieje. (bo e.address == "coś tam").
Ja bym proponował coś takiego:

Code:
create view AddressDef {
   virtual objects address {  if ( exist(e.address) ) return e.address as a;
                                        else return "coś tam" as noA; }
                                 //albo po prostu return "coś tam"; - tylko tego nie jestem do końca pewien

   on_update (newAddress) { if( exist(a) )  a = newAddress;
                                        else e :< create (newAddress as address);}                   
}


I exist( a ) przestaje być herezją godną zgrabnego stosika.
stencel
Posted: Sunday, February 27, 2005 9:54:24 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
I exist( a ) przestaje być herezją godną zgrabnego stosika.


Super! O to chodzilo wlasnie. Troche sie trudno typuje tu virtual objects, bo trzeba uzyc typu variant, ale za to uzytkownik perspektywy ma super komfort.

Na Jowisza! To chyba jedyna dyskusja w Internecie, w ktorej dyskutanci dochodza do zbieznych wnioskow.

Mysle ze warto zdobyc opinie Szefa, wyglosic seminarium i szykowac papiór.
radamus
Posted: Monday, February 28, 2005 10:13:22 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
To może najpierw spróbujmy podsumować. Ja zacznę:
Zbierając podsumowanie Hanki i rozważania Krzyśka:

Obiekty rzeczywiste mogą być:

Proste
Złożone
Pointerowe

1. Dla zakładanej przezroczystości obiekty wirtualne powinny odzwierciedlać ten podział. Dotychczas mieliśmy wirtualne obiekty:
Proste - definiowane przez perspektywę nie posiadającą podperspektyw.
Mogą mieć przeciążone operację on_retrieve, on_update, on_delete.

Złożone - definiowane przez perspektywę posiadającą podperspektywy
Mogą mieć przeciążone operację on_update, on_delete, on_insert.


Obecnie mamy jeszcze wirtualne obiekty pointerowe.
Nie mogą one mieć podperspektyw bo obiekt pointerowy jest na swój sposób obiektem prostym.
Mogą mieć przeciążone operację on_update, on_delete, (?) (ale ... o tym za chwilę)


virtual objects ustala ziarna obiektu pointerowego.
point_to ustala referencję obiektu na który wskazuje pointer. Ja tam jeszcze umieszczałem nazwę tzn. pisałem

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


Ale nie wiem czy jest to konieczne. Normalnie nested(pointer) działa tak, że pobiera nazwę wskazywanego obiektu na podstawie referencji, którą pointer przechowuje. Zakładając, że bez względu na to jak bardzo wirtualny byłby nasz pointer, point_to zwraca referencję to jesteśmy w stanie tę nazwę pobrać. W tym wypadku point_to jest tak na prawdę on_retrieve (co zauważył Krzysiek). Bo przecież dereferencja na pointerze zwraca wartość przechowywaną przez pointer czyli referencję. Nie przychodzi mi do głowy przykład, który pokazywałby, że on_retrieve może zwrócić coś innego niż point_to. Jeżeli nie jest to możliwe to opcje syntaktyczne są dwie. Albo

Code:
virtual objects nazwaWirtPointera {...}
point_to {...}

lub coś al'a Hani propozycja
Code:
virtual objects nazwaWirtPointera as pointer {...}
on_retrieve {} //wtedy obowiązkowo


Bo tak czy inaczej musimy poinformować mechanizm, że ma do czynienia z wirtualnym pointerem. Identyfikator wirtualny pointera musi być odróżnialny od standardowego.
<flag „I’m virtual pointer”, view def id, seed>

point_to lub on_retrieve byłoby wykorzystywane przez funkcje nested oraz w razie zapytania, które wymusza dereferencję na pointerze np.:

Code:
for any((BestUniversity where name =="PJWSTK").bestAttendees as bs) bs == ref(Student where name == "Poe");


Oczywiście przy takim założeniu nie można byłoby w perspektywie zabronić dereferencji pointera (point_to lub on_retrieve są obowiązkowe). Pytanie czy to dobrze czy nie? Dodatkowo możę się okazać, że on_retrieve może zwrócić coś innego niż point_to. Ale tu przydałby się przykład.



2)Nie wprowadzamy ograniczeń na to co możę zwracać sack perspektywy definiującej wirtualny pointer. Natomiast wprowadzamy ograniczenie na to co może zwracać point_to/on_retrieve. Musi to być identyfikator (UWAGA! lub wirtualny identyfikator - ale to może się odbyć niejawnie). Czyli wirtualny pointer może prowadzić do wirtualnego obiektu i moim zdaniem nie powinno tu być większych problemów. Tylko proponowałbym wrócić do dyskusji nt. on_create_pointer...

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


Kwestie rozważanie ostatnio tzn. wirtualne identyfikatory, które jednak muszą mieć seed i związane z tym tematy aktualizacji nieistniejących w rzeczywistości danych proponowałbym podsumować osobno/przenieść do innego wątku.
stencel
Posted: Monday, February 28, 2005 11:57:15 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
Bo tak czy inaczej musimy poinformować mechanizm, że ma do czynienia z wirtualnym pointerem. Identyfikator wirtualny pointera musi być odróżnialny od standardowego.
<flag „I’m virtual pointer”, view def id, seed>


No wlasnie dlaczego? Musze przyznac, ze tego nie rozumiem. Dla obiektow materialnych takich problemow nie ma. OID materialnego obiektu pointerowego niczym nie rozni sie np. od OID materialnego obiektu atomowego.
radamus
Posted: Tuesday, March 01, 2005 11:00:56 AM

Rank: Advanced Member

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

No wlasnie dlaczego? Musze przyznac, ze tego nie rozumiem. Dla obiektow materialnych takich problemow nie ma. OID materialnego obiektu pointerowego niczym nie rozni sie np. od OID materialnego obiektu atomowego.


Mechanizm funkcji nested jest przecież inny w przypadku wirtualnego pointera.

Dla zwykłych identyfikatorów wirtualnych mamy na stosie:
Code:
-------------------------------------------------------
bindery do sacków podpespektyw (jeżeli są )
--------------------------------------------------------
nested(seed)
--------------------------------------------------------

Dla pointera mamy:
Code:
----------------------------------------------------------------
rezultat point_to czyli binder do wskazywanego obiektu.
---------------------------------------------------------------
nested(seed)
---------------------------------------------------------------


Ergo: mechanizm musi wiedzieć czy to identyfikator wirtualnego pointera czy zwykły wirtualny identyfikator. Dla złożonych i prostych obiektów wirtualnych mechanizm jest ten sam. Dla pointerów inny.




stencel
Posted: Tuesday, March 01, 2005 12:43:39 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
Ergo: mechanizm musi wiedzieć czy to identyfikator wirtualnego pointera czy zwykły wirtualny identyfikator. Dla złożonych i prostych obiektów wirtualnych mechanizm jest ten sam. Dla pointerów inny.


Uwazam jednak ze nie musi (ten Twoj argument odpada).

Mechanizm funkcji nested moze budowac taka strukture:

Code:
---------------------------------------------------------------------------------
rezultat point_to czyli binder do wskazywanego obiektu (jesli point_to)
---------------------------------------------------------------------------------
bindery do sacków podpespektyw (jeżeli są )
---------------------------------------------------------------------------------
nested(seed)
---------------------------------------------------------------------------------


Czyli dokladnie to co dla zlozonych. Wkladamy sekcje jesli odpowiednie podobiekty (podperspektywy lub point_to) istnieja.

Jest to znacznie lepsze niz tworzenie dwoch rodzajow identyfikatorow wirtualnych.
radamus
Posted: Wednesday, March 02, 2005 6:38:05 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Tak jak piszesz jest ok ... chyba zacząłem trochę zbyt implementacyjnie. Załóżmy, że faktycznie nie ma identyfikatora wirtualnego pointera.
Wirtualne obiekty proste -> nested(seed)
Wirtualne obiekty złożone -> nested(seed) bindery do sack'ów podpespektyw
Wirtualne obiekty proste -> nested(seed), binder(rezultat point_to)

Na poziomie syntaktycznym definicji wirtualnego pointera jest, załóżmy, point_to. Jak są podperspektywy to nie ma point_to i vice versa.

radamus wrote:
(...) point_to lub on_retrieve byłoby wykorzystywane przez funkcje nested oraz w razie zapytania, które wymusza dereferencję na pointerze (...). Oczywiście przy takim założeniu nie można byłoby w perspektywie zabronić dereferencji pointera (point_to lub on_retrieve są obowiązkowe). Pytanie czy to dobrze czy nie? Dodatkowo możę się okazać, że on_retrieve może zwrócić coś innego niż point_to. Ale tu przydałby się przykład.


Tylko co z tym on_retrieve??

stencel
Posted: Wednesday, March 02, 2005 4:06:56 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
Tylko co z tym on_retrieve??


on_retrieve moze byc tylko w perspektywach atomowych (tj. bez podperspektyw i point_to). Jest wywolywane tylko wtedy gdy uzytkownik wywola na obiekcie funkcje deref.
radamus
Posted: Wednesday, March 02, 2005 7:42:12 PM

Rank: Advanced Member

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

on_retrieve moze byc tylko w perspektywach atomowych (tj. bez podperspektyw i point_to). Jest wywolywane tylko wtedy gdy uzytkownik wywola na obiekcie funkcje deref.


on_retrieve jest wywoływane wszędzie tam, gdzie potrzebna jest dereferencja. Nie tylko gdy użytkownik wywoła jawnie deref ale również niejawnie, (gdy jest R-value, przy porównaniach, itp.).
Ale nie o to mi chodziło.

Jeżeli założymy, że w wirtualnych pointerach nie ma on_retrieve, a jego funkcję pełni point_to, które oczywiście jest wykorzystywane przede wszystkim przez operatory niealgebraiczne, to nie będziemy mogli zabronić dereferencji. Co można zrobić w przypadku wirtualnych obiektów atomowych. Mogę nie definiować on_retrieve zabraniając dereferencji tak samo jak mogę nie definiować on_update zabraniając aktualizacji. Point_to jest obligatoryjne w wirtualnym pointerze więc nie mamy takiej możliwości. Nie zakładam, że to źle czy dobrze. Taki będzie skutek tego założenia.
stencel
Posted: Wednesday, March 02, 2005 9:25:02 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
radamus wrote:
Point_to jest obligatoryjne w wirtualnym pointerze więc nie mamy takiej możliwości. Nie zakładam, że to źle czy dobrze. Taki będzie skutek tego założenia.


To rzeczywiscie moze byc zle. Pod warunkiem ze jestesmy w stanie wyobrazic sobie taka sytuacje, ze ktos definiuje wirtualny pointer i zabrania przejscia po nim. Czy to ma sens? Czy mozemy wskazac taka praktyczna sytuacje?

Na razie nie wyobrazam sobie czegos takiego.
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.259 seconds.