P1 (programozási) minta-feladat ------------------------------- Segédeljárás: Egy Prolog kifejezés szimmetrikus, ha a szimmetrikus pozíciójú argumentumai azonosak (azaz egy n-argumentumú kifejezés szimmetrikus, ha 1. és n., 2. és (n-1).,..., i. és (n+1-i). argumentuma azonos). Az argumentum nélküli kifejezéseket szimmetrikusaknak tekintjük. Írjon Prologban egy olyan eljárást, amely egy tetszőleges Prolog kifejezésről megállapítja, hogy az szimmetrikus-e! Az azonosság eldöntésére az ==/2 beépített eljárást használhatja. Vigyázat, a kifejezés lehet változó! % szimmetrikus(Kif): igaz, ha Kif szimmetrikus. % :- pred szimmetrikus(univ::in). Példák: | ?- szimmetrikus(f(g(X),h(a,a),j(3,4,3))). ----> no | ?- szimmetrikus(f(g(a,a),h(2),g(a,a))). ----> yes | ?- szimmetrikus(f(1)). ----> yes | ?- szimmetrikus(1-X). ----> no | ?- szimmetrikus(X-X). ----> yes | ?- szimmetrikus(X). ----> yes Teljes feladat: A szimmetrikus/1 predikátum segítségével írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezés összes szimmetrikus részstruktúráját felsorolja. A részkifejezések előfordulási sorrendjét őrizze meg! Vigyázat, a kifejezés lehet változó és benne is előfordulhatnak változók! % szimmetrikus_resze(Kif, Resz): Resz a Kif-nek szimmetrikus részstruktúrája, % :- pred szimmetrikus_resze(univ::in, univ::out). Példák: | ?- szimmetrikus_resze(f(1,a,1), R). R = f(1,a,1) ? ; R = 1 ? ; R = a ? ; R = 1 ? ; no | ?- szimmetrikus_resze(f(2+1+1,3+3+3), R). R = 2 ? ; R = 1 ? ; R = 1 ? ; R = 3+3 ? ; R = 3 ? ; R = 3 ? ; R = 3 ? ; no | ?- szimmetrikus_resze(g(X,Y), R). R = X ? ; R = Y ? ; no A segédeljárásra 11 pont, a teljes feladatra 21 pont kapható. P2 (programozási) minta-feladat ------------------------------- Segédeljárás: Egy számlistában vízesésnek hívunk egy olyan legalább kételemű, folyamatos részlistát, amely szigorúan monoton csökkenő, a szomszédos elemek különbsége legalább 3, és egyik irányba sem terjeszthető ki ezen tulajdonságok megtartásával. Írjon egy olyan Prolog eljárást, amely eldönti, hogy egy egészekből álló lista elején egy vízesés áll-e, és visszadja a vízesés első és utolsó elemét, valamint a bemeneti listának a megtalált vízesés utáni részét! Ha a bemeneti lista nem vízeséssel kezdődik, az eljárás hiúsuljon meg! % kezdo_vizeses(L, K, V, M): az L egészlista elején egy vízesés áll, amelynek % első eleme K, utolsó eleme V, az utána következő elemek listája M. % :- pred kezdo_vizeses(list(int)::in, int::out, int::out, list(int)::out). Példa: | ?- kezdo_vizeses([], K, V, M). no | ?- kezdo_vizeses([1,2,-5,20,15,12,7,3,0], K, V, M). no | ?- kezdo_vizeses([2,-5,20,15,12,7,3,0], K, V, M). K = 2, V = -5, M = [20, 15, 12, 7, 3, 0] ? ; no Teljes feladat: A kezdo_vizeses/3 predikátum segítségével írjon egy olyan Prolog eljárást, amely felsorolja egészek egy adott listájában az összes benne megtalálható vízesés első és utolső elemét! A vízeséseket előfordulási sorrendjükben vegye sorra! % vizeses(L, K, V): K és V egy az L egészlistában előforduló vízesés első % illetve utolsó eleme. % :- pred vizeses(list(int)::in, int::out, int::out). Példa: | ?- vizeses([0,2,5,5], K, V). no | ?- vizeses([1,2,-5,20,15,12,7,3,0], K, V). K = 2, V = -5 ; K = 20, V = 0 ; no A segédeljárásra 11 pont, a teljes feladatra 21 pont kapható. P3 (programozási) minta-feladat ------------------------------- Egy A atom egy N nemnegatív egésszel vett szorzatán az A atom N-szeri egymás után fűzésével kapott atomot értjük. Segédeljárás: Írjon Prolog nyelven egy eljárást amelynek bemenete egy N nemnegatív egész és egy A atom, kimenete pedig N és A szorzata! % szorzata(N, A, NA): NA az N nemnegatív egész és az A atom szorzata. % :- pred szorzata(int::in, atom::in, atom::out). Példák: | ?- szorzata(2, korte, NA). ----> NA = kortekorte ? ; no | ?- szorzata(0, korte, NA). ----> NA = '' ? ; no Teljes feladat: A szorzata/3 eljárás segítségével, könyvtári eljárások használata nélkül készítsen el egy Prolog eljárást, amely egy számokból és atomokból a + és * operátorokkal felépített a-kifejezés értékét kiszámítja! Ha A atomot, N nemnegatív egészet jelöl, akkor az AKif-fel jelölt a-kifejezéseket a következő nyelvtani szabállyal jellemezhetjük: AKif ---> A | N*AKif | AKif*N | AKif+AKif. A + operátor a konkatenálást jelöli, a * operátor pedig a segédfeladatban definiált szorzást. % erteke(OpKif, Ertek): Az OpKif operátoros ábrázolású % fent definiált alakú kifejezés értéke Ertek. % :- pred erteke(univ::in, atom::out). Példák: | ?- erteke(alma, E). E = alma ? ; no | ?- erteke(ba*2, E). E = baba ? ; no | ?- erteke(2*ba, E). E = baba ? ; no | ?- erteke(alma+'_korte'+2*'_barack', E). E = alma_korte_barack_barack ? ; no A segédeljárásra 11 pont, a teljes feladatra 21 pont kapható. P4 (programozási) minta-feladat ------------------------------- Nevezzünk lineáris kifejezésnek egy tetszőleges olyan Prolog kifejezést, amely egész számokból és atomokból a +, - és * kétargumentumú operátorokkal épül fel, úgy, hogy a * operátor egyik oldalán mindig szám áll! Egy ilyen kifejezés, aritmetikai kifejezésnek tekintve mindig leegyszerűsíthető egy olyan összeggé, amelynek tagjai `szám*atom' vagy `szám' alakúak, és minden atom csak egyszer szerepel benne. Írjon egy olyan Prolog eljárást, amely egy adott lineáris kifejezés és adott atom esetén, meghatározza az adott atom együtthatóját a kifejezés leegyszerűsített alakjában! % egyhat(Kif, Atom, Egyutthato): Atom atom együtthatója a Kif lineáris % kifejezés egyszerűsített alakjában Egyutthato. % :- pred egyhat(univ::in, atom::in, int::out). | ?- egyhat(x, x, E). E = 1 ? ; no | ?- egyhat(x*3, x, E). E = 3 ? ; no | ?- egyhat(3, x, E). E = 0 ? ; no | ?- egyhat( 2*(x*3+1+y), x, E). E = 6 ? ; no | ?- egyhat( 2*(x*3+1+y), y, E). E = 2 ? ; no | ?- egyhat( (2+3*a)*2 - 3*(b - a), a, E). E = 9 ? ; no | ?- egyhat( (2+3*a)*2 - 3*(b - a), b, E). E = -3 ? ; no Könnyítésként felteheti, hogy a kifejezés * alakú tényezőket tartalmaz '+'/2 és '-'/2 struktúrákkal összekapcsolva. Példa: | ?- egyhat(2*a - 3*b + 3*a, b, E). E = -3 ? ; no Az eredeti feladat 21, a könnyített változat 11 pontot ér.