A GAP programozási nyelv

Típusok

A gap nem típusos nyelv, egy változó típusát nem lehet megadni.

Alaptípusok

Egész számok

Az gap tetszőleges hosszú egész számot tud kezelni, a hosszának csak a mem óriánk szab határt. Például:

gap> Factorial(50); 30414093201713378043612608166064768844377641568960512000000000000 gap> Factorial(10000); <>

Fontos, hogy habár a nyelv egyáltalán nem támogat lebegőpontos szá- mokat, egész számok kifejezéseként nyilván minden racionális számot leírhatunk. Emiatt nincsenek számábrázolási hibák, a gap minden racionális számot egzaktul tárol. Azonban ennél bonyolultabb kifejezések is léteznek.

A gap E(n) alakban tudja tárolni az n-ik primitív egységgyököt, így ezek hatványainak racionális együtthatós lineáris kombinációit is képes kezelni. Ezek a racionális test ún. ciklotomikus bővítései. Ez nem fedi le az összes algebrai számot, hanem csak részét. Ezek közé tartozik pl. a
21/2 = E(8) − E(8)3 = Z8 − Z38 , ugyanis:
(Z8 − Z38)2=Z28 + Z68 - 2Z48 = Z4 - Z4-2(-1)=2
Pédák:

gap> 256/8192; 1/32 gap> Sqrt(2); E(8)-E(8)^3

Láthatjuk tehát, hogy a gap nem csak racionális, de bizonyos típusú komplex számokat is kezel (ugyanis i = E(8)) egzaktul.

Permutációk

A nyelv elsősorban csoportelméleti algoritmusok megírására készült. Egy csoportot legegyszerűbben úgy tudunk kezelni, ha keresünk egy vele izomorf permutációcsoportot.

Egy halmaz bijektív leképezéseit önmagára a csoport permutációinak nevezzük. A gap az egész számok permutációit képes kezelni, ezek jelölését pár példán keresztül mutatjuk be:

Permutációk példa

Egy halmaz permutációinak szorzatán a permutációk, mint függvények kompozícióját értjük, a permutáció hatása egy elemen az a szám, amelyet a függvény rendel hozzá, ezt a gap ^ operátora jelzi.
Példák:

gap> a:=(1,2,3);; b:=(4,5);; gap> a*b; (1,2,3)(4,5) gap> a*a; (1,3,2) gap> b*b; () gap> 1^a; 2

Karakterek

A karakterket aposztrófok közé kell tenni. Például: 'a'

Rekordok

A példa magáért beszél:

gap> rec( a:=1, b:=[123], c:="string" ); rec( a := 1, b := [ 123 ], c := "string" )

Listák

A gap listáinak különböző typusú elemei is lehetnek:

gap> l:=[1, "hello", [123] ]; [ 1, "hello", [ 123 ] ]

Vagy tartalmazhatja önmagát (amit a ~ szimbólum jelöl):

gap> l[4]:=l; [ 1, "hello", [ 123 ], ~ ]

De hagyhatunk lyukakat a listában:

gap> l:=[,2]; [ , 2 ] gap> l[1]; List Element: [1] must have an assigned value not in any function Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' after assigning a value to continue

Listát megadhatunk intervallumként is az első és utolsó elemével [1..100], vagy (ha nem egyesével növekszik) az első, a második, és az utolsó elemével [0,5..100].
A gap a sztringeket a karakterek listájaként értelmezi.

Objektum és elem

Hiba jelzésére a User könyvtár (statikus osztály) Leave metódusa szolgál. Azokat a föggvényeket, amelyek a User::Leave metódust hívják leave-elő függvényeknek nevezzük. A User::Leave hívás logikailag megfelel a C++-ban megszokott throw-nak, mely az adott típusú kivételt dobja. Symbian-ban a kivétel típusa egy számot (hibakódot) jelent.

Megkülönböztetjük két objektum egyenlőségét (equality), és azonosságát (identity), Két objektum akkor azonos, ha fizikailag ugyanott helyezkednek el a memóriában, akkor egyenlő, ha az = metódus igaz (a metódusokról ké- sőbb). Ezzel megkülönböztetjük az objektum, és az elem kifejezéseket, ahol az elem az objektumok kategóriájának az ekvivalenciaosztályait jelenti.

Két nem identikus objektum akkor lehet egyenló egymással, ha:
1. Az egyik a másik másolalata.
2. Ugyanazt az értéket msáképp tárolja.
3. egy matematikai ekvivalenciareláció miatt a két objektum ekvivalens.

Változhatóság, másolhatóság

Egy objektum lehet vátoztatható (mutable), vagy nem (immutable), illetve lehet másolható, vagy nem. Az ezzel kacsolatos függvények:

IsMutable(obj)Megmondja, hogy az objektum változtatható-e.
MakeImmutable(obj)Megváltoztathatatlanná teszi az obj objektumot.
Immutable(obj)A StructuralCopy segítségével másolatot készít, és azt megváltoztathatatlanná teszi.
IsCopyableMegmondja, hogy az objektum másolható-e.
ShallowCopy(obj)Egy másolatot készít az objektumról (tehát a másolat nem lesz azonos, csak egyenlő), viszont az objektum részobjektumait nem másolja (tehát ezek identikusak lesznek).
StructuralCopy(obj)Ha az objektum változtatható, lemásolja, ha nem nem másolja le. Ha másolódott, rekurzívan StructuralCopy-val másol ódik minden részobjektuma.

A GAP típuskonstrukciója a megfelelő matematikai fogalmakra épít, teh át itt nem osztályokról, hanem kategóriákról beszélünk. Öröklődés valamilyen értelemben van, de nem hasonlítható az objektumorientált nyelvekben lévőhöz. A GAP-es terminológia mindent objektumnak nevez, hiszen minden az objektumok kategóriájába tartozik.

Típus

Minden objektumnak van típusa, minden típus objektum, ami tartalmazza az objektum családját (family), és a szűrőit (filters). Egy típus családja a FamilyOfTypes. Természetesen minden család is objektum, és ezek családja a FamilyOfFamilies. A családnak azt kell teljesítenie, hogy ha két objektum egyenlő, egy családba kell tartozniuk.

Szűrők

A szűrők logikai függvények, azaz egy adott objektumhoz rendelnek igaz, vagy hamis értéket. Minden szűrőnek van egy rangja, amely egy szám (ez később a műveleteknél még fontos lesz).

A szűrőkön értelmezett a logikai és művelet, pl: IsMutable and IsCopyable. Egy ilyen szűrő rangja az implikált szűrők rangjának összege. Az egyszerű szűrők azon, amelyek nem implikálnak más szűrőt. Ezek a szűrők ismertek minden objektumra, és az értékeit az objektum egy bitlistában tárolja. A rangjuk mindig 1.

Speciális szűrők:
1. A kategóriák (Category) olyan szűrők, amelyek meghatározzák, hogy mely műveletek megengedettek az objektumon, de ez nem jelenti azt, hogy a művelet sikeres is lesz. Példa: Legyen m egy mátrix. A * operátor értelmes, mert a mátrix benne van az IsMultiplicativeElement kategóriában. Az Inverse művelet is értelmes, hiszen benne van az IsMultiplicativeElementWithInverse kategóriában, ennek ellenére a m nem feltétlen invertálható. Ekkor az Inverse metódus hibát jelez. Hasonlóképpen az 1/0 kifejezés is hibát okoz annak ellenére, hogy az osztás értelmezett az egész számokon (IsInt).
2. A reprezentáció (representation) olyan szűrő, amely az objektum konkr ét tárolását adja meg. A nyelvben létező reprezentációk:
IsInternalRepBelső reprezentáció, ezeket tekintettük az alaptípusoknak.
IsDataObjectRepOlyan objektum, amely reprezentációját nem a GAPben definiálták, hanem a GAP kernel része, így a belső strukt úrája nem elérhető.
IsComponentObjectRep, IsPositionalObjectRepEzek a GAPben létrehozott reprezentációk. Ezekből tudunk saját reprezentá- ciót készíteni, (amelyekből még sajátokat) azzal a feltétellel, hogy csak egyszeres öröklődés létezik.
3.Az Attribútumok tulajdonképpen egyrészt műveletek, másrészt szűrők. Ha a művelet végeredménye ismert, akkor lesz a szűrő igaz. Ilyen attribútum egy csoport mérete:

gap> g:=FreeGroup(1); gap> HasSize(g); false gap> Size(g); infinity gap> HasSize(g); true

A tulajdonságok olyan speciális attribútumok, amelyek értéke igaz, vagy hamis. Ez egyrészt önmaga egy szűrő, másrészt egy szűrő az is, hogy ismerjük-e az értékét.
Pl. ha egy absztrakt kétműveletes halmazt kezelünk, ilyen tulajdons ág az IsAssociative, IsCommutative, IsAntiCommutative, IsLDistributive, IsRDistributive. Ezeket a GAP használni fogja a műveletek kiértékelésekor, miután ismertek.