@t[Az Escher-quine]~~META:date created = 2019.08.02., 01:13~~ //[[the_escher_quine|(in English)]]// Ez kicsit bonyolult lesz, emberek. A cím két úr nevéből van, akik közül a másodikat közszóként használjuk, kezdjük ővele. Willard Van Orman Quine (1908–2000), a huszadik század egyik legnagyobb hatású filozófusa, matematikai logikus, nyelvfilozófus, számos jelentős gondolat megfogalmazója, mint például a Quine-paradoxon. Ezzel a paradoxonnal magam is találkozom, amikor nyelvet tanulok. @s5[A Quine-paradoxon] @jr[ablakzsiraf]Mondjuk látok egy képet, amin mindenféle dolgok vannak. (Ez itt az Ablak–Zsiráfból való, 11. kiadás, 1971.) Ez magyar anyanyelvű gyerekeknek készült, akik olvasni is tudnak, a szöveget életkorukhoz és tudásszintjükhöz tervezték, de képzeljük el, hogy én most nyelvtanulás céljából tanulmányozom. (Tényleg használok olyan könyveket, amiket lett anyanyelvű kisiskolás gyerekeknek írtak.) Középen a fehér ruhás emberhez az van írva, hogy PÉK, és valamit berak valahová egy lapáttal. Vagy kivesz. Nem tudok magyarul, nem ismerem ezt a szót, és nem ismerem föl, hogy mi történik a képen. Lehet, hogy amúgy gyerek vagyok, és tényleg nem láttam még péket munkában. Vajon rájövök, hogy azok ott maizék, amiket a krāsnsba rak bele, és ez az ember egy maiznieks? És ez egy egyszerű eset, mert a valóságban, amikor az anyanyelvét tanuló kisgyerek valaminek a nevét hallja, akkor legtöbbször ambivalens a szituáció: anya rámutat egy tárgyra, de abban az irányban egy csomó tárgy van, és ha a gyerek azonosítja is a helyeset, netán anya a kezébe veszi, akkor is: az a szó vajon annak az adott konkrét tárgynak a neve, vagy absztrahálnia kell tárgyak egy kategóriájára, és ha igen, melyikre, avagy a tárgy valamely tulajdonságára, vagy valamilyen vele kapcsolatos cselekvésre? Láttam egy filmet valakiről, aki ezer darab tárgynak a nevét ismeri, mindegyik név egy-egy adott konkrét tárgy neve, de egyikről sem tud absztrahálni valamilyen tárgycsoportra, -kategóriára, tárgyak valamilyen tulajdonságára, semmilyen absztrakcióra nem képes. Noha felnőtt – viszont kutya. A kisgyerektől elvárjuk, hogy a //labda// szót hallva rövid időn belül ne az adott individuális tárgyra asszociáljon, hanem a szót absztrahálja mindazon tárgyakra, amik gömb alakú, eldobva gurulni, repülni, pattogni tudó játékok, ugyanakkor ha ő egy magyar gyerek, akkor azt is elvárjuk tőle, hogy a (szintén korosztályának szókincsébe tartozó) //golyó// szótól, illetve tárgykategóriától is meg tudja különböztetni, ami egy cseppet sem egyszerű egy magyarul tanuló felnőttnek, akinek angol az anyanyelve, és neki mind a kettő //ball.// @s5[A quine-ok] Hát ilyesmikkel is foglalkozott Quine professzor, és ez adta az indíttatást Douglas Hofstadternek, hogy az ő nevét használja a rekurzió egy sajátos formájára. 1979-ben megjelent //Gödel, Escher, Bach: az örök aranyfonat// című könyvében (a magyar cím tőlem) //quine-oknak// nevezi el azokat a számítógépprogramokat, amik elindítva kiírják saját forráskódjukat. Így például az alábbi ZX Spectrumra írt program: @zxcolor[0f0|10 PRINT "Ez itt egy szöveg"] @zxcolor[0f0|20 PRINT "(kétsoros)"] elindítás után ezt fogja kiírni: @zx[Ez itt egy szöveg] @zx[(kétsoros)] Ez tehát nem quine. Ahhoz, hogy quine lehessen, a föntebb zölddel írt szöveget kellene kiírnia. No de azt csak akkor fogja kiírni, ha így írjuk: @zxcolor[f00|10 PRINT "10 PRINT ""Ez itt egy szöveg"""] @zxcolor[f00|20 PRINT "20 PRINT ""(kétsoros)"""] (az idézőjelben dupla idézőjelet kell írni, ha idézőjelet szeretnénk kiíratni). Csakhogy azzal, hogy a szöveget átírtuk erre a pirossal írt változatra, az lett az elvárás, hogy a piros szöveget írja ki, ne a zöldet. Csak akkor lenne quine. (Ezek a példák egy képzeletbeli Spectrumról vannak, amelyik tud ékezetes betűket is; könnyen meg lehet tanítani neki őket.) Azt hiszem, elég nyilvánvaló, hogy quine-t írni nem egyszerű. Ennek ellenére vannak egysoros quine-ok is, mint például ez a Python nyelven írt programocska: print((lambda s:s%s)('print((lambda s:s%%s)(%r))')) ami, ha lefuttatjuk egy Pythonul tudó gépen, természetesen azt fogja kiírni, hogy print((lambda s:s%s)('print((lambda s:s%%s)(%r))')) Ennélfogva egy quine-t //megírni// érdekes agytorna, de //lefuttatni// az unalom netovábbja, pontosan tudjuk, hogy mi fog történni. Meg fog jelenni ugyanaz a szöveg, amit addig is láttunk. A programozók azonban imádnak játszani, ezért létrejöttek mindenféle egyéb quine-ok. @s5[Quine-változatok] **Csaló quine-ok.** Egy quine-nak elő kell állítania a saját forráskódját még egyszer, nem pedig megnéznie a memóriát vagy a lemezt és elolvasnia a forráskódot. A csaló quine-ok igenis ezt teszik. Természetesen bármely BASIC nyelven értő házi számítógépen egy olyan program, aminek teljes tartalma 1 LIST azt fogja kiírni, hogy 1 LIST – tehát quine, de csal, nem készíti el azt a szöveget még egyszer, hogy ''1'' (szóköz) ''L'' ''I'' ''S'' ''T'', csak kiolvassa a memóriából a programot és kilistázza. **Uroboroszok.** Az ógörögöknél, akiknek az életben gyakran előforduló dolgok mindegyikére volt szavuk, //uroborosz// saját farkába harapó kígyót jelentett. Azt nem tudom, hogy a kígyók mikor csinálnak effélét, de az uroboroszprogramok megteszik. Adott nyelven (például C+`+-ban) írunk egy programot, ami elindítva egy másik nyelven (például Javában) írt program forráskódját produkálja; ha ez utóbbi programot elindítjuk, akkor kiírja az eredeti C+`+ nyelvű program forráskódját. De ez egyszerű eset. [[https://github.com/mame/quine-relay|Endó Juszke]] írt egy Ruby nyelvű programot, ami produkál egy Rust nyelvű programot, ami egy Scala nyelvűt, ami egy Scheme nyelvűt, és így tovább, ábécérendben Zsh-ig, aztán jön az A+, Ada, AFNIX és így tovább az ábécén végig, egészen a Ruby nyelvig, összesen //százhuszonnyolc// programnyelvet mozgat meg avégett, hogy aztán visszakapja ugyanazt a Ruby nyelvű forráskódot, amivel kezdte. **Multiquine-ok.** Több különböző nyelven írt program csoportja, amelyek mindegyike képes arra, hogy a csoport bármelyik tagjának a forráskódját kiírja (ideértve a sajátját is), s egy adott paraméter segítségével választhatunk, hogy melyiket kérjük. **Sugárzásbiztos quine-ok.** Olyan quine-ok, amikből ha bármely (egy darab) karaktert elveszünk, akkor is képesek kiírni a forráskódjukat, éspedig a törölt karakter helyreállításával. Nyilván ki lehet még ilyeneket találni. Most éppen kitaláltam a //mutálódó quine//-t, a sugárzásbiztos ihletésére: kiírja a forráskódját, de elképzelhető, hogy egy karakter hiányozni fog belőle, vagy eggyel több lesz, vagy valamelyik helyett egy másik áll, viszont ettől még továbbra is quine és ki tudja írni a forráskódját, csak megvan az esély ugyanezekre a változásokra, és így tovább, tehát ha az eredeti quine-t lefuttatjuk százszor, akkor kapunk száz quine-gyereket, amik csak egy ponton különböznek az eredetitől, és ha ezeket is lefuttatjuk száz-száz alkalommal, akkor kapunk tízezer quine-unokát, amik már két ponton különböznek, és így tovább, és így tovább. Halvány fogalmam sincs, hogy lehet-e ilyet írni csakugyan. Az én programozói tudásommal az egész kérdéskörhöz hozzá se szagolok. Viszont mindazok a programtípusok, amikről eddig szólt a cikk, egyvalamiben megegyeznek. Amikor elindítjuk őket, egy //szöveget// kapunk. Ami ugyebár a saját forráskódjuk vagy egy másik programé, mindenesetre egy szöveg. Amit be lehet tölteni szövegszerkesztőbe, olvasni lehet, ki lehet nyomtatni. Ezt a cikket egy olyan program kedvéért írtam, aminek a kimenete nem szöveg, hanem cselekvés. Ennek ellenére ez is quine. Ez az //Escher-quine.// @s5[Az Escher-quine] {{ escher-quine.mp4 }} A kis videón az látható, hogy Nagy Dániel A. egy programot gépel be [[https://en.wikipedia.org/wiki/ZX_Spectrum|ZX Spectrum]]on. A Sinclair-gépeken ezt így csinálják, a képernyő alsó részén van a szerkesztőablak, egyetlen sornyi, és ha az megtelik, akkor fölfelé növekszik; amikor kész (megnyomtuk az Entert), akkor fölugrik a felső képernyőrészbe. A gépelés elég sajátosan történik a Spectrum tarkabarka billentyűzetén: a kurzor nem vonalka és nem kocka, hanem egy villogó betű, @zxinv[K] @zxinv[E] @zxinv[L] @zxinv[C] @zxinv[G] közül valamelyik, és a betűtől függ, hogy a lenyomott billentyű milyen jelet vagy szót ad. Például az @basic[N] billentyű @zxinv[L] módban kis @zx[n] betűt ad, @zxinv[C] módban @zx[N]agyot, @zxinv[K] módban a @zx[NEXT] utasításszót, @zxinv[E] módban az @zx[INKEY$] függvénynevet, de ismeri még az @zx[OVER] szót és a @zx[,] vesszőt is. Ez az egy gomb. Ez a Sinclair-gépek egyedi sajátossága, a nyolcvanas évek elején ez egy úttörő kezdeményezés volt, és mellesleg a Spectrum-rajongók mindmáig imádják. Én legalábbis. Szóval ezért váltakozik ott folyton a @zxinv[K] és az @zxinv[L], és ezért jelennek meg a BASIC-szavak egyben, nem pedig betűnként, mert az egy-egy billentyűlenyomás. Direkt rajta van a billentyűzeten a Spectrum BASIC teljes szókincse. @jc[spectrum] Nos, most, hogy tisztáztuk, mi történik a videón, elmondom, hogy //nem ez// történik a videón. A videó nem azt mutatja, ahogy Dániel begépeli a programot, hanem a program futása látható rajta. Ez egy quine, hiszen kiírja a saját forráskódját, de nem szövegként, hanem eljátssza, hogy begépeli. Az utánzás szinte tökéletes. Hogy mégis utánzás, azt onnan lehet tudni, hogy az olyan szavak, mint @zx[RESTORE], @zx[READ], @zx[DATA], @zx[FLASH], @zx[LEN], @zx[STR$] és @zx[CHR$], úgy jelennek meg, hogy a kurzor előzőleg nem vált @zxinv[E]-re, pedig egy valódi Spectrumon (vagy akár egy emulátoron) ezeket a szavakat nem lehet elérni anélkül, hogy előzőleg (a @basic[Caps Shift] és a @basic[Symbol Shift] billentyűk együttes lenyomásával) @zxinv[E]-re változtatnánk a kurzort, s ezután még ugye rá kell tennünk az ujjunkat a megfelelő kulcsszó billentyűjére, ami időbe telik, ezalatt az @zxinv[E]-nek egy rövid időre látszania kellene, ha Dániel maga gépelne. De hát kit zavar ez? A világegyetem mint egész önmagánál egyszerűbb modellel nem írható le. A Spectrum is egy kicsi világegyetem. @s5[Az elnevezés] Azt a nevet, hogy @basic[Escher-quine], én adtam neki. A címbeli másik úrnak, M. C. Eschernek van ez az ismert rajza: @jc[lw355-mc-escher-drawing-hands-1948] A címe //Drawing Hands (Tekenen),// és 1948-ban jelent meg. Természetesen erre a rajzra már hivatkozott Hofstadter is az említett könyvben, Escher neve benne is van a címében. De így, hogy @basic[Escher-quine] (angolul kötőjel nélkül, külön írva), nem találtam meg a neten, így van esély, hogy ezt én találtam ki. Definícióm szerint //Escher-quine az a quine, ami nem saját forráskódját (önmaga kész állapotát) reprodukálja, hanem saját forráskódjának **elkészítését.**// @zx[(© Láng Attila D., 2019.)] Az eljárás nem egészen ismeretlen a számítástechnika történelmében. Sok filmben láthatók feliratok, amik úgy jelennek meg, mintha azokat egy ember gépelné be egy számítógépbe; ilyen például az 1979-es [[https://www.youtube.com/watch?v=IJaypC51Dds|A fekete lyuk.]] A számítástechnikai szakirodalomban valaha külön kategóriát képviseltek azok a magazinok, amiket programként írtak meg és terjesztettek, és ezek egy részében az oldalak nem egyszerűen csak megjelentek, hanem a betűket sorban egymás után írta ki a gép, mintha egy ember gépelné be őket éppen akkor. Magam is írtam ilyet. No de ezt quine-nal kombinálni, olyan quine-t írni, ami a saját begépelését imitálja – ez világcsúcs. @s5[A quine kódja] Mivel az olvasó böngészője nem Spectrum, meglehetős vesződségembe került egy önmagánál egyszerűbb modellel leírni a Spectrumot és olyan listát készíteni, ami olyan, mint egy igazi Spectrumon. Legalábbis az enyémben olyan. Szürke háttéren jelenik meg fekete betűkkel, igazi Spectrum-betűtípussal. Remélem, az olvasónál is. Úgy az igazi.