Rekurzió 3. Szlávi Péter ELTE Informatika Szakmódszertani Csoport 2019.05.30. Rekurzió 3. Szlávi Péter ELTE Informatika Szakmódszertani Csoport szlavi@ludens.elte.hu http://izzo.inf.elte.hu/szlavi 2000 Rekurzió 1
Tartalom 0 Bevezetés 1 Rekurzív specifikáció 2019.05.30. Tartalom 0 Bevezetés 0.1 A rekurzió lényege; „klasszikus” példák 0.2 A rekurzió helye a programkészítés folyamatában 1 Rekurzív specifikáció 1.1 Formalizmus 1.2 Példák 2 Rekurzív specifikáció és rekurzív algoritmus 3 Rekurzió megvalósítása nem rekurzív környezetben 3.1 Problémák 3.2 Példák 3.3 A valódi megoldás ötlete, avagy mit tesz egy fordító program? 2019.05.30. Rekurzió 3 Rekurzió 1
Tartalom 4 Rekurzió és iteráció 5 Rekurzív típusok 4.1 Oda 4.2 Vissza 2019.05.30. Tartalom 4 Rekurzió és iteráció 4.1 Oda 4.1.0 Bajok a rekurzióval 4.1.1 Rekurzív függvények 4.1.2 Jobbrekurzió 4.1.3 Balrekurzió 4.2 Vissza 4.2.0 A „dolog értelme” 4.2.1 Ciklusok átírása 5 Rekurzív típusok 5.1 Nevezetes rekurzív adatszerkezetek 5.2 Rekurzív adatszerkezetek definiálása 5.3 A struktúrabejárás mint a feldolgozás „kerete” 2019.05.30. Rekurzió 3 Rekurzió 1
Tartalom 6 Rekurzív adattípusok: fák 6.1Bináris fák 2019.05.30. Tartalom 6 Rekurzív adattípusok: fák 6.1Bináris fák 6.2 Nem bináris fák 6.3 B-fák 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok 5.1 Nevezetes rekurzív adatszerkezetek 2019.05.30. 5 Rekurzív típusok 5.1 Nevezetes rekurzív adatszerkezetek ÜresLista Lista := Egyesítés(Elem,Lista) ÜresFa BinFa:= Egyesítés(Elem,BinFa,BinFa) ÜresFa Fa := Egyesítés(Elem,Fák) A sokaságoknál definiált Üres művelet. A sokaságoknál definiált Egyesítés művelet. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Az Egyesítés két értelmezési lehetősége („filozófia”): sokaság (a mikroszerkezet hangsúlyozása: azonos típusú Elemekből épül föl valahogyan) egy „furcsa” direktszorzat (a makroszerkezet hangsú-lyozása: egyenrangú, de nem azonos típusú részekből, még-pedig Elemből és valami az egészre emlékeztetőből áll). A részek elérésének programozástechnikája: értékmegosztással (láncolással/mutatóval) értékmásolással. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) A rekurzív adatszerkezet jellemzői: sokaság: azonos típusú elemekből áll akár 0 db elemet tartalmazhat Üres: rekurzív „nullelem”, kitüntetett konstans Fraktál (=önhasonlóság) tulajdonság: a részei ugyanolyan szerkezetűek, mint az egész nem lineárisan rendezett (azaz nem sorozatféle): bármely elemének 0, 1, 2… rákövetkezője lehet. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 5.2 Rekurzív adatszerkezetek definiálása 5.2.0 Rekurzió egy típuskonstrukciós eszköz Megjegyzések: Csak 1 nem rekurzív komponens („mező”) lehet. (Ez nem valódi korlátozás!!!) A rekurzív komponensek típusa a „teljes” (definiálandó) típussal kötelezően megegyező. Szelektorok elő fognak fordulni paraméterként, ezért bevezetjük a Szelektor kulcs-szót. (Tulajdonképpen egy spec. típus, l. később.) Típus TRek=Rekurzió (szelektor1:TElem szelektor2 :TRek …) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Nem véletlen a szintaktikai hasonlóság a rekorddal. A műveleteik is sokban emlékeztetnek majd egymásra. Sajátos gond: nehéz az „egzakt” szintaxisú leírása. Oka –akárcsak a rekordnál–: a tetszőleges számú paraméter (bár itt csak kétféle típusú lehet). 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Sokaság filozófiájával aposztrofálva a rekurzív ágat: Típus TLista=Rekurzió (elem:TElem köv:TLista) Példák: Típus TLista=Rekurzió (elem:TElem farok:TLista) Típus TBinFa=Rekurzió (elem:TElem bal, jobb:TBinFa) Típus TFa=Rekurzió (elem:TElem ágak:Sorozat(TFa)) A Sorozat csak jelzése valamely ismert sorozatfélének (Tömb, AbsztraktSorozat …) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 5.2.1 Rekurzió mint sokaság Sajátossága: A rekurzió elemek sokasága, így szükséges lesz kezeléséhez egy kezdő (gyökér)-elemre (amely a teljes szerkezetet „összetartja”), egy aktuális elemre (amelyre a legtöbb művelet vonat- kozni fog). 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 5.2.1.1 Algebrai specifikáció Az alábbiakban csak a legjellegzetesebb műveleteit vesszük figyelembe: Típus Rekurzió(Elem; rszel1,…:Rek): [Megállapodás: Szel={rszel1,…}] Asszociált műveletek: Üres:Rek Üres?(Rek):Logikai Létrehoz(Elem):Rek Illeszt(Rek,Rek,Szel):Rek {NemDef} Leválaszt(Rek,Szel,Rek):RekRek {NemDef} Elem(Rek):Elem {NemDef} Rész(Rek,Szel):Rek {NemDef} Módosít(Rek,Elem):Rek {NemDef} Elsőre(Rek):Rek {NemDef} Következőre(Rek,Szel):Rek {NemDef} Illeszt(mit,mihez,min keresztül) Leválaszt(miről,min keresztül,mire): miről’ mire’ 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Elején?(Rek):Logikai {NemDef} Végén?(Rek):Logikai {NemDef} Jelölések: r,r’,r”,rr,rr’:Rek – általában a felső vesszők időbeliségre utalnak e:Elem s:Szel „=”:RekRekLogikai, strukturális és elemérték-szintű azonosság Axiómák: 1º Üres – axióma r=Üres Üres?(r) Elem(r)=NemDef Elején?(r)=NemDef Végén?(r)=NemDef 2º Létrehoz – axióma r=Létrehoz(e) Üres?(r) Elején?(r) Végén?(r) Elem(r)=e Üres?(Rész(r,s)) 3º Illeszt – axióma Illeszt(r,Üres,s)=r Elem(r)NemDef Illeszt(rr,r,s)=r’ Rész(r’,s)=rr Illeszt(mit,mihez,min keresztül) Létezik aktuális elem. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Nem létezik aktuális elem. 3’º Illeszt – hiba-axióma Elem(r)=NemDef Illeszt(rr,r,s)=NemDef 4º Leválaszt – axióma [rr’,rrrr’] Elem(r)NemDef Rész(r,s)=rs Üres?(rr) Leválaszt(r,s,rr)=(r’,rr’) rr’=rs Üres?(Rész(r’,s)) 4’º Leválaszt – hiba-axióma Elem(r)=NemDef Üres?(rr) Leválaszt(r,s,rr)=NemDef 5º Módosít – axióma Elem(r)NemDef Módosít(r,e)=r’ Elem(r)=e 5’º Módosít – hiba-axióma Elem(r)=NemDef Módosít(r,e)=NemDef Leválaszt(miről,min keresztül,mire): miről’ mire’ 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 6º Elsőre-Következőre – axióma Üres?(r) Elsőre(r)=r’ Elem(r’)=e Illeszt(rr,r’,s)=r” Elem(Elsőre(r”))=e … hf: a Következőre megfogalmazása … 6’º Elsőre-Következőre – hiba-axióma Elem(r)=NemDef Elsőre(r)=NemDef Következőre(r)=NemDef 7º Elején?-Végén? – axióma Elem(r)NemDef Elején?(Elsőre(r)) Következőre(r)=r’ r’NemDef Elején?(r’) … hf: a Végén? megfogalmazása 7’º Elején?-Végén? – hiba-axióma Elem(r)=NemDef Elején?(r)=NemDef Végén?(r)=NemDef 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 5.2.1.2 A rekurzió exportmodulja a modulfejben tisztázni kell a felhasználás szinta- xisát, de ezt most nem lehet teljesen egzakt módon, mivel változó számú paraméterrel rendelkezik. Típus TRek= Rekurzió(eszel:TElem,rszel1,…:TRek) ExportModul Rekurzió(eszel:TElem,rszel1,…:TRek): Sárga rész – kitérés: a precízebb leírás érdekében. Formálisabban (szintaktikus ellenőrzés lehetőségét lehetővé téve): ExportModul Rekurzió(Konstans eszel:Szelektor, Típus TElem, Konstans rszel1,…:Szelektor, Típus TRek): Másként Rekurzió(eszel:TElem,rszel1,…:TRek) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Kísérlet az exportmodul „egzakttá” tételére: * bináris fa rekurzív típusának definiálása: * … és exportmodulja: Lényeg: a típuskonstrukciónál csak a minimálisan szük- séges számú paraméter szerepeljen! Nem erőltetjük a rekurzivitás explicit kifejezését. Típus TBFSzel=(elem,bal,jobb) [felsorolási típus] TElem=… TBF=Rekurzió(TElem,TBFSzel) ExportModul Rekurzió(Típus TElem, Típus TRSzel): [hivatkozás a(z) * nem rekurzív komponensre: Min’TRSzel szelektorral * 1. rekurzív komponensre: Következő(Min’TRSzel) * … * utolsó rekurzív komponensre: Max’TRSzel] Kitérés: a precízebb leírás érdekében. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Most a szokásos, nem teljesen egzakt jelöléssel folytatjuk. Exportmodul: ExportModul Rekurzió(eszel:TElem,rszel1 …:TRek): Függvény Üres?(Konstans r:TRek):Logikai [Uf: a „teljes” r üres-e?] Konstans Üres:TRek [Uf: 0 db elemből álló struktúra] Eljárás Létrehoz(Konstans e:TElem, Változó r:TRek) [Uf: r 1-elemű rekurzív struktúra] Megjegyzés: nem küszöbölhető ki, ui.: az Illeszt az egyetlen „bővítő” operátor, ami bővíteni csak akkor tud, ha legalább 1-elemű rekurzív struktú- rákkal manipulál. Eljárás Illeszt(Konstans mit:TRek, Változó mihez:TRek, Konstans melyik:Szelektor) [Ef: Üres?(mihez) vagy Üres?(Rész(mihez,melyik) Uf: Két azonos típusú rekurzív szerkezetet egymáshoz illeszt, a mihez akt-jánál, a melyik-en keresztül] Visszatérés a „hagyományokhoz”. Az Ef és Uf csak informálisan szerepelnek, sőt az „általánosan” visszatérő Ef majd csak a végén, egyszer… Precízebben: Szelektor’TRek 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Eljárás Leválaszt(Változó miről:TRek, Konstans melyik:Szelektor, Változó mire:TRek) [Ef: Üres?(mire) Uf: a miről leválasztja az akt melyik szelektorán kapcsolódó részt, s a mire akasztja; az adott ágat üressé teszi] Függvény Elem(Konstans r:TRek):TElem [Uf: az akt elem értéke] Függvény Rész(Konstans minek:TRek, melyik:Szelektor):TRek [Uf: a minek struktúra az akt-ról a melyik szelektorán „lógó” rész-struktúrát adja vissza értékmegosz- tással, azaz annak a memóriacímét, mutatóját] Eljárás Lemásol(Konstans mit:TRek, Változó mire:TRek) [Ef: Üres?(mire) Uf: mit akt-ból kiinduló rész pontos másolatát a mire akasztja] 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Eljárás Felszabadít(Változó r:TRek) [Uf: felszabadítja az akt-ból eredő rész-struktúra által lefoglalt memóriaterületet] Eljárás Módosít(Konstans e:TElem, Változó r:TRek) [Uf: az r akt elemét e-re módosítja] Eljárás Elsőre(Változó r:TRek) [Uf: a gyökért teszi aktuálissá] Eljárás Következőre(Változó r:TRek Konstans melyik:Szelektor) [Uf: az akt elem melyik szelektorán továbblép, ha lehet] Függvény Elején?(Konstans r:TRek):Logikai [Uf: az akt elem a struktúra gyökéreleme-e?] Függvény Végén?(Konstans r:TRek):Logikai [Uf: az akt elem valamelyik terminális elem-e?] Modul vége. Nem mondtuk ki, legtöbb operáció előfeltételének elvárt része: létezzék az akt elem, és melyik≠Min’Szelektor! 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Ez a típus „glo-bális” neve is. Megvalósítási modul: Modul Rekurzió(eszel:TElem,rszel1,…:TRek): Reprezentáció [láncolt] Típus TRElem=Rekord(eszel:TElem, rszel1, … :TRElem’Mutató) TRek=Rekord(gyökér:TRElem’Mutató akt:TRElem’Mutató) Változó r:TRek Implemetáció Függvény Üres?(Konstans r:TRek):Logikai Üres?:=r.gyökér=Sehova Függvény vége. Konstans Üres:TRek(Sehova,Sehova) Eljárás Létrehoz(Konstans e:TElem, Változó r:TRek): Lefoglal(r.gyökér,TRElem(e,Sehova,…)) Eljárás vége. Pascal-ban: ^TRElem Ez dönt a típus me-mórialefoglalásról. Szokásos mező még: hiba:Logikai Ettől most eltekintünk. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Eljárás Illeszt(Konstans mit:TRek, Változó mihez:TRek, Konstans melyik:Szelektor): [Ef: mihez.gyökér=Sehova (mihez.aktSehova melyik≠eszel TRElem(mihez.akt).melyik=Sehova)] Elágazás Üres?(mihez) esetén mihez:=mit egyéb esetben TRElem(mihez.akt).melyik:=mit.gyökér Elágazás vége Eljárás vége. Eljárás Leválaszt(Változó miről:TRek, Konstans melyik:Szelektor, Változó mire:TRek): [… hf …] Jól-definiáltság Hogy ne vesszen el elem Pascal-ban: mihez.akt^.melyik 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Függvény Elem(Konstans r:TRek):TElem [Ef: r.akt≠Sehova] Elem:=TRElem(r.akt).eszel Függvény vége. Függvény Rész(Konstans minek:TRek, melyik:Szelektor):TRek [Ef: minek.akt≠Sehova melyik≠eszel] Rész:=TRek(TRElem(minek.akt).melyik [gyökér] TRElem(minek.akt).melyik [akt]) Függvény vége. Eljárás Lemásol(Konstans mit:TRek, Változó mire:TRek): [… hf …] Eljárás Felszabadít(Változó r:TRek) [… hf … Figyelem: értékmegosztás miatt többszörös felhasználás lehetséges!!! (hivatkozás-számláló)] Eljárás Módosít(Konstans e:TElem, Változó r:TRek): [Ef: r.akt≠Sehova] TRek(r.akt).eszel:=e Eljárás vége. Itt bukkan fel először a hivatkozás-számlálás szükségessége. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Eljárás Elsőre(Változó r:TRek): [Ef: r.akt≠Sehova r.gyökér≠Sehova] r.akt:=r.gyökér Eljárás vége. Eljárás Következőre(Változó r:TRek, Konstans melyik:Szelektor): [Ef: r.akt≠Sehova melyik≠eszel TRElem(r.akt).melyikSehova] r.akt:=TRElem(r.akt).melyik Eljárás vége. Függvény Elején?(Konstans r:TRek):Logikai [… hf …] Függvény Végén?(Konstans r:TRek):Logikai [… hf …] Inicializálás r:=Üres Modul vége. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Példaként egy érték megkeresése a TRek típuskonstrukció műveleteire építve: Függvény RekKer(Konstans r:TRek, e:TElem):TRek [Ef: Elején?(r) Uf: er Elem(RekKer(r,e))=e Elején?(RekKer(r,e)) er Üres?(RekKer(r,e))] Változó melyik:Szelektor’TRek kész:Logikai rm:TRek Ha Üres?(r) akkor RekKer:=Üres különben … 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) … különben Ha Elem(r)=e akkor RekKer:=r különben melyik:=Következő(Min’Szelektor’TRek) kész:=Hamis Ciklus amíg melyikMax’Szelektor’TRek és nem kész rm:=RekKer(Rész(r,melyik),e) kész:=nem Üres?(rm) és Elem(rm)=e Ha melyik<Max’Szelektor’TRek akkor melyik:=Következő(melyik) különben kész:=Igaz Elágazás vége Ciklus vége RekKer:=rm Elágazás vége Elágazás vége Függvény vége. A nem rekurzív mező szelektora. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Az értékmegosztás problematikájának egy példája: A bf „kétszeresen balra eső” részfájának leválasztása: Elsőre(bf); Leválaszt(Rész(bf,bal),bal,bf2) bf Rész(bf,bal) Leválaszt(Rész(bf,bal),bal,bf2) Elsőre(bf) Rész(bf,bal),bal 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) A helyfelszabadítás és az értékmegosztás problemati- kájának egy példája: Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf Elsőre(bf) jbf:=Rész(bf,jobb) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) A helyfelszabadítás és az értékmegosztás problemati- kájának egy példája: Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf bf:=Rész(bf,bal) jbf 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) A helyfelszabadítás és az értékmegosztás problemati- kájának egy példája: Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf jÉrt:=Feldolgozás(jbf); bÉrt:=Feldolgozás(bf) jbf 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) A helyfelszabadítás és az értékmegosztás problemati- kájának egy példája: Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf Felszabadít(jbf) jbf ? Problémák: A felszabadítás után „csellengő” hivatkozások keletkeznek! Mi lesz az értékadás után a baloldali változó „egykori” értékével? 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Egy tisztességes megoldás ötlete: Hivatkozás- („tulajdonos”-) számlálás. Felszabadítás intelligensebbé tétele. Megvalósítás felé: Reprezentáció-módosítás minden rekurzív elemnek tulajdonos-számlálót Implementáció-módosítás (hol kell a számlálóval foglalkozni?) Értékadáskor Eljáráshíváskor a paraméterek vonatkozásában Függvényhíváskor a paraméterek, fv.-érték vonatkozásában Kifejezésekben Tartós értékmegosztás történik: Csak időleges értékmegosztás történik: (=nem kell) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Érdemes a részleteket meggondolni Pl. a b:=fv(bb) értékadást valósítsuk meg az Értékadás(b,fv(bb)) eljárással. Eljárás Értékadás(Változó b:TRek, Konstans bb:TRek): TulajdonostCsökkent(b)[b-től kiindulva az összes elem tulajdonos- számlálóját 1-gyel csökkenti, és a 0 tulajdonos-számúak helyét felszabadítja] b:=bb [címmegosztás] TulajdonostNövel(b) [b-től kiindulva az összes elem tulajdonos- számlálóját 1-gyel növeli] Eljárás vége. L. a BinFa esetére kidolgozott modult! 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Az algebrai specifikáció: hf. 5.2.2 Rekurzió mint rekord-analogon Előzetes megjegyzések: ez az „igazi”, rekurzióhoz illeszkedő elképzelés a leírás nem teljesen „egzakt” formális okok miatt ExportModul Rekurzió(eszel:TElem,rszel1,…:TRek): Függvény Üres?(Konstans r:TRek):Logikai Konstans Üres:TRek Operátor Mező(Konstans r:TRek, melyik:Szelektor):TElem TRek Másnéven r.melyik [Ef: melyik=eszel melyik=rszel1 … Uf: az r melyik szelektora által kijelölt komponense, amely ha melyik=eszel, akkor TElem, ha melyik=rszeli, akkor TRek típusú] 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Következmény: Nincs szükség néhány korábbi műveletre. Pl.: Elem, Rész, Következőre… Nem megvalósítható az Elsőre. Operátor Legyen(Változó r:TRek, Konstans melyik:Szelektor, er:TElem TRek) Másnéven r.melyik:=er [Ef: (melyik=eszel er:TElem) (melyik=rszeli er:TRek) Uf: az r melyik szelektora által kijelölt komponense értékül kapja az er-t, vagyis „r.melyik:=er”, amely ha melyik=eszel, akkor TElem, ha melyik=rszeli, akkor TRek típusú adatok között megy végbe] Modul vége. Hf: megoldani az új jelölésekkel. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Egy „szintaktikai” példa: Típus TBinFa=Rekurzió(ért:TElem, bal,jobb:TBinFa) Változó b1,b2:TBinFa e:TElem b1:=Üres; b2:=TBinFa(e,Üres,b1) [egy-elemű bifa] … e:=b2.ért; b1:=b2.bal [a binfa részeihez férés] … b1.ért:=e; b1.bal:=b2.jobb [binfa részek módosítása] b2:=TBinFa(b1.ért,b1.jobb,b1.bal) [binfa-komponálás] 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Vö.: a sokaság-szerűvel! Modul Rekurzió(eszel:TElem,rszel1,…:TRek): Reprezentáció Típus TRElem=Rekord(eszel:TElem rszel1, …: TRElem’Mutató) TRek=TRElem’Mutató Változó r:TRek Implementáció Függvény Üres?(Konstans r:TRek):Logikai Üres?:=r=Sehova Függvény vége. Konstans Üres:TRek(Sehova) Operátor Mező(Konstans melyik:Szelektor, r:TRek):TElem TRek Másnéven r.melyik Mező:=TRElem(r).melyik Operátor Vége. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Operátor Legyen(Változó r:TRek, Konstans melyik:Szelektor, er:TElem TRek) Másnéven r.melyik:=er TRElem(r).melyik:=er Operátor Vége. Inicializálás r:=Üres Modul vége. Megjegyzés: ez esetben is választható az „intelligens”, tulajdo- nos-számlálós implementáció, amely a TRek-típusú értékadások intelligens megvalósítását jelenti 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) 5.3 Struktúrabejárás mint a feldolgozás kerete Feldolgozás sokaság-szemlélettel: Feldolgozás rekord-szemlélettel: Eljárás RFeld(Konstans r:TRek): Ha nem Üres?(r) akkor EFeld(Elem(r)) RFeld(Rész(r,rszel1)) RFeld(Rész(r,rszel2)) … Elágazás vége Eljárás vége. Eljárás RFeld(Konstans r:TRek): Ha nem Üres?(r) akkor EFeld(r.eszel) RFeld(r.rszel1) RFeld(r.rszel2) … Elágazás vége Eljárás vége. 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) Lehet tetszőleges elem-feldolgozás. Példák: Listabejárás: Eljárás LBejár(Konstans l:TLista): Ha nem Üres?(l) akkor Ki: Elem(l) LBejár(Rész(l,farok)) Eljárás vége. Elhagyható lenne! Hívása: Elsőre(l); LBejár(l) Eljárás LBejár(Konstans l:TLista): Ha nem Üres?(l) akkor Ki: l.elem LBejár(l.farok) Eljárás vége. Hívása: LBejár(l) 2019.05.30. Rekurzió 3 Rekurzió 1
5 Rekurzív típusok (folytatás) 2019.05.30. 5 Rekurzív típusok (folytatás) az algoritmikus rekurzió iterációvá alakítása egyszerű a jobbrekurzió miatt: Eljárás LBejár(Konstans l:TLista): Változó sl:TLista sl:=l; Elsőre(sl) Ciklus amíg nem Üres?(sl) Ki: Elem(l) sl:=Rész(sl,farok) Ciklus vége Eljárás vége. sl:=Következőre(sl,farok) Végén?(sl) Eljárás LBejár(Konstans l:TLista): Változó sl:TLista sl:=l Ciklus amíg nem Üres?(sl) Ki: Elem(l) sl:=sl.Farok Ciklus vége Eljárás vége. 2019.05.30. Rekurzió 3 Rekurzió 1