Prolog vizsgafeladat-sorok (c) Szeredi Peter, 1994-1998 =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(750615)). :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, NL), findall(A, (member(A, NL), A > 0'4), AL), reverse(AL, [U,V|_]), !, put(V), put(U), nl. p(_N) :- write('nem megy'), nl. Megoldás: p(N) először kiírja N értékét, és egy újsort. Ezután az N-ben előforduló 4-nél nagyobb értékű számjegyek közül az utolsó kettőt írja ki, ha van ilyen; különben a 'nem megy' szöveget. Példák: ?- p(750615). 750615 65 ?- p(740214). 740214 nem megy 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. Feltételezzük, hogy a lists könyvtár be van töltve. a. ?- 4*3 is X, X is 3*4. b. ?- append([], L, X), var(X). c. ?- X is 5//4, X == 5//4. d. ?- U is 21/5, (U < 4 -> X is 4-U ; X is U-4). e. ?- a+b+c =.. X. f. ?- name(abc, [U|V]), name(X, V). Megoldások: a. hiba {INSTANTIATION ERROR} b. siker, X = L c. meghiúsulás d. siker, X = 0.2 e. X = [+,a+b,c] f. X = bc 3. Írjon Prolog eljárást az olyan legfeljebb háromjegyű pozitív számok felsorolására, amelyek megegyeznek (decimális) jegyeik négyzetösszegének kétszeresével. % jegynegyzet2(N): N egyenlő jegyei négyzetösszegének kétszeresével % :- pred jegynegyzet2(int::out). Megoldás: jegynegyzet(N) :- between(0, 9, A), between(0, 9, B), between(0, 9, C), N is A*100+B*10+C, N > 0, N =:= 2*(A*A+B*B+C*C). % between definícióját lásd a jegyzetben. 4. Legyen Kif egy Prolog kifejezés, amely számokból a négy alapművelet (+,-,*,/) segítségével épül fel. a. Írjon egy flki(Kif) Prolog eljárást, amely egy adott Kif kifejezés fordított lengyel alakját írja ki, az egyes elemeket szóközökkel választva el. Például: ?- flki(1+2*(3-4)/5). kimenete: 1 2 3 4 - * 5 / + b. Írjon egy fl(Kif, L) Prolog eljárást, amely egy adott Kif kifejezés fordított lengyel alakját az L listában előállítja. Törekedjék hatékony megoldásra (append-et ne használjon)! Például: ?- fl(1+2*(3-4)/5, L). eredménye: L = [1,2,3,4,-,*,5,/,+] Nem kötelező rész: A feladatot oldja meg úgy, hogy ne csak a négy alapműveletre, hanem tetszőleges kétargumentumú struktúrakifejezésekre is működjék. Például: ?- fl(f(1+2,g(4,5)), L). eredménye: L = [1,2,+,4,5,g,f] Megoldás: a. flki(X+Y) :- !, flki(X), tab(1), flki(Y), tab(1), write(+). flki(X*Y) :- !, flki(X), tab(1), flki(Y), tab(1), write(*). flki(X-Y) :- !, flki(X), tab(1), flki(Y), tab(1), write(-). flki(X/Y) :- !, flki(X), tab(1), flki(Y), tab(1), write(/). flki(X) :- number(X), write(X). % tab(1) helyett természetesen jó a write(' ') is. Általánosítva: flki(Kif) :- Kif =.. [Muv,X,Y], !, flki(X), tab(1), flki(Y), tab(1), write(Muv). flki(Kif) :- number(Kif), write(Kif). b. fl(Kif, L) :- fl(Kif, [], L). % fl(Kif, L0, L): Kif fordított lengyel alakját L0 elé % fűzve kapjuk L-t. fl(X+Y, L0, L) :- !, fl(Y, [+|L0], L1), fl(X, L1, L). fl(X-Y, L0, L) :- !, fl(Y, [-|L0], L1), fl(X, L1, L). fl(X*Y, L0, L) :- !, fl(Y, [*|L0], L1), fl(X, L1, L). fl(X/Y, L0, L) :- !, fl(Y, [/|L0], L1), fl(X, L1, L). fl(N, L, [N|L]) :- number(N). Általánosítva: fl(Kif, L) :- fl(Kif, [], L). % fl(Kif, L0, L): Kif fordított lengyel alakját L0 elé % fűzve kapjuk L-t. fl(Kif, L0, L) :- Kif =.. [Muv,X,Y], !, fl(Y, [Muv|L0], L1), fl(X, L1, L). fl(N, L, [N|L]) :- number(N). DCG-vel: fl(Kif, L) :- fl(Kif, L, []). % fl(Kif, L0, L): Kif fordított lengyel alakját L0 elejéről % leszedve marad L. fl(X+Y) --> !, fl(X), fl(Y), [+]. fl(X-Y) --> !, fl(X), fl(Y), [-]. fl(X*Y) --> !, fl(X), fl(Y), [*]. fl(X/Y) --> !, fl(X), fl(Y), [/]. fl(X) --> {number(X)}, [X]. DCG-vel, általánosítva: fl(Kif, L) :- fl(Kif, L, []). fl(Kif) --> {Kif =.. [Muv,X,Y]}, !, fl(X), fl(Y), [Muv]. fl(Kif) --> {number(Kif)}, [Kif]. 5. N-ed rendű mu-listának hívjuk azt a listát, amelynek szerkezete: [m, u, m, u, u, ...., m, u, ..., u] 1. 2. N. N db u Azaz a lista pontosan N 'm' atomot tartalmaz, és az i-edik 'm'-et pontosan i darab 'u' atom követ. Írjon egy Prolog eljárást, amely egy adott listáról eldönti, hogy az egy mu-lista-e, és ha igen, meghatározza hanyad-rendű. % mu(L, N): Az L lista egy N-ed rendű mu-lista. % :- pred mu(list(atom)::in, int::out). Példa: | ?- mu([m,u,m,u,u], N). eredménye: N = 2 . | ?- mu([m,u,m,u,u,u], N). meghiúsul. Megoldás: mu(L, N) :- mu(0, L, N). % mu(I, L, N): L egy N-edrendű mu-lista I-edik farka (azaz az % N-edrendű mu-lista elejéről egy I-edrendű mu-lista % lehagyásával áll elő). mu(N, [], N). mu(I, L, N) :- L = [m|L1], I1 is I+1, u(I1, L1, L2), mu(I1, L2, N). % u(I, L0, L): az L0 lista elejéről lehagyva I darab 'u' atomot % marad az L lista. u(0, L, L). u(I, [u|L0], L) :- I1 is I-1, u(I1, L0, L). DCG-vel: mu(L, N) :- mu(0, N, L, []). % mu(I, N, L, L0): L elejéről egy N-edrendű mu-lista I-edik farkát % leszedve marad L0 mu(N, N) --> []. mu(N0, N) --> [m], {N1 is N0+1}, u(N1), mu(N1, N). % u(I, L0, L): az L0 lista elejéről lehagyva I darab 'u' atomot % marad az L lista. u(0) --> []. u(I) --> [u], {I1 is I-1}, u(I1). =========================================================================== A megoldásokban segédeljárásként használhatja a Prolog jegyzetben definiált eljárásokat (de csak ezeket). 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(750615)). :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, NL), reverse(NL, [_,DC|_]), name(D, [DC]), length(L, D), append(L, [E|_], NL), put(E), nl. Megoldás: p(N) először kiírja N értékét, és egy újsort. Meghatározza N utolsó előtti jegyét (ennek értéke lesz D), majd kiírja N D+1-ik jegyét és egy újsort. Példák: ?- p(750615). 750615 5 ?- p(740224). 740224 0 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. Feltételezzük, hogy a lists könyvtár be van töltve. a. ?- X is +(1,2), X =:= 10//3. b. ?- member(X, [1,2,3]), !, X > 2. c. ?- name(X, [0'7,0'0]). d. ?- X = 1*2, X @< 2*1. e. ?- arg(2, [1], X). f. ?- X =.. [1,2,3]. Megoldások: a. siker, X = 3 b. meghiúsulás c. siker, X = 70 d. siker, X = 1*2 e. X = [] f. hiba 3. Írjon Prolog eljárást két azonos hosszúságú számlista skalárszorzatának képzésére! (Az [x1, ..., xn] és [y1, ..., yn] listák skalárszorzatának értéke az x1*y1+ ... + xn*yn szám.) Használjon jobbrekurziót! % skalarszorzat(A, B, S): A és B egyenlő hosszúságú számlisták % skalárszorzata S. % :- pred skalarszorzat(list(int)::in, list(int)::in, int::out). Példa: | ?- skalarszorzat([1,2], [3,4], S). eredménye S = 11 Megoldás: skalarszorzat(A, B, S) :- skalarszorzat(A, B, 0, S). skalarszorzat([], [], S, S). skalarszorzat([A|Ak], [B|Bk], S0, S) :- S1 is S0+A*B, skalarszorzat(Ak, Bk, S1, S). 4. Írjon olyan Prolog eljárást, amely egy adott atomban megkeresi egy adott részatom előfordulását, és megadja ennek indexpozicióját (1-től számozva)! Visszalépéskor legyen hajlandó az összes előfordulást felsorolni! % atom_index(Atom, Resz, Index): Az Atom atom részeként szerepel a Resz % atom az Index pozíción. % :- pred atom_index(atom::in, atom::in, int::out). | ?- atom_index(tanitani, ani, I). I = 2 ? ; I = 6 ? ; no Megoldás: atom_index(Atom, Resz, Index) :- name(Atom, A), name(Resz, R), list_index(A, R, 1, Index). list_index(A, R, I, I) :- append(R, _, A). % vagy prefix(R, A). list_index([_|A], R, I, Index) :- I1 is I+1, list_index(A, R, I1, Index). prefix([], _). prefix([X|P], [X|L]) :- prefix(P, L). 5. Népszerű feladványtípus a kővetkező: egy adott számsorozat elemei közé '+' vagy '-' jeleket kell helyezni, hogy az így kapott aritmetikai kifejezés értéke egy adott szám legyen. Írjon két Prolog eljárást az ilyen típusú feladványok megoldására! a. % osszeg(L, Ossz, JL): L nem-üres számlista elemei közé rakva a JL % jellista elemeit a kapott kifejezés értéke Ossz. % (JL egy elemmel rövidebb mint L, elemei + vagy - jelek.) % :- type jel ---> + ; -. % :- pred osszeg(list(int)::in, int::in, list(jel)::out). Az osszeg eljárás visszalépéskor az összes lehetséges megoldást sorolja fel! Példa: | ?- osszeg([2,3,4,5,6,7], 13, JL). JL = [+,+,+,+,-] ? ; JL = [-,-,+,+,+] ? ; no b. % osszegki(L, Ossz): Kiírja az összes olyan igaz egyenlőséget, amelynek % baloldalán az L számlista elemei szerepelnek + vagy - jelekkel % elválasztva, a jobboldalán pedig az Ossz szám. % :- pred osszegki(list(int)::in, int::in). | ?- osszegki([2,3,4,5,6,7], 13). 2 + 3 + 4 + 5 + 6 - 7 = 13 2 - 3 - 4 + 5 + 6 + 7 = 13 nincs (tobb) megoldas Megoldás: % osszeg(L, Ossz, JL): L nem-üres számlista elemei közé rakva a JL % jellista elemeit a kapott kifejezés értéke Ossz. osszeg([X|L], S, JL) :- ossz(L, JL, X, S). % ossz(L, JL, S0, S): Az [S0|L] számlista elemei közé rakva a JL % jellista elemeit a kapott kifejezés értéke S. ossz([], [], S, S). ossz([X|L], [J|JL], S0, S) :- hozzavesz(J, S0, X, S1), ossz(L, JL, S1, S). % hozzavesz(J, S0, X, S) :- Az S0 J X kifejezés értéke S. hozzavesz(+, S0, X, S) :- S is S0+X. hozzavesz(-, S0, X, S) :- S is S0-X. % osszegki(L, Ossz): Kiírja az összes olyan igaz egyenlőséget, amelynek % baloldalán az L számlista elemei szerepelnek + vagy - jelekkel % elválasztva, a jobboldalán pedig az Ossz szám. osszegki([X|L], S) :- ossz(L, JL, X, S), write(X), ki(L, JL), format(' = ~d~n', [S]), fail. osszegki(_,_) :- format('nincs (tobb) megoldas~n', []). % ki(L, JL) a két azonos hosszúságú lista elemeit összefésülve kiírja % szóközökkel elválasztva. ki([], []). ki([X|L], [J|JL]) :- format(' ~w ~d', [J,X]), ki(L, JL). =========================================================================== A megoldásokban segédeljárásként használhatja a Prolog jegyzetben definiált eljárásokat (de csak ezeket). 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(750615))? Magyarázza meg, miért! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, NL), append(_, [A|BL], NL), put(A), BL = [B|_], B > A, !, nl. p(_) :- write(' vege'), nl. Megoldás: p(N) először kiírja N értékét, és egy újsort. Felbontja N-et számjegyei kódlistájára, majd mindaddig írja ki a számjegyeket, amig ezek monoton csökkenő sorozatot alkotnak. Ha talál egy olyan számjegyet amely az előzőnél nagyobb, akkor egy újsorral befejezi a kiírast. Ha az egész szám egy monoton csökkenő jegysorozatból áll, akkor a végére kiírja a ' vege'szöveget, és egy újsort. Példák: ?- p(750615). 750 5 ?- p(741111). 741111 741111 vege 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. Feltételezzük, hogy a lists könyvtár be van töltve. a. ?- X = 8//3. b. ?- name(1+2, X). c. ?- functor([1], F, X). d. ?- append([1], U, X), f(1) =.. U. e. ?- findall(V, (member(V,[9,7,0,1,2,4]), V>3), X). f. ?- X = [1,2,3], arg(2, X, 2). Megoldások: a. siker, X = 8//3 b. hiba c. siker, X = 2 d. siker, X = [1,f,1] e. siker, X = [9,7,4] f. meghiúsulás 3. Írjon egy olyan Prolog eljárást, amely meghatározza egy számlista pozitív (azaz 0-nál nagyobb) elemeinek számát! Használjon jobbrekurziót! % pozszam(L, P): Az L számlistában P darab pozitív elem van. % :- pred pozszam(list(int)::in, int::out). Példa: | ?- pozszam([1,-2,0,3], P). eredménye: P = 2 Megoldás: pozszam(L, P) :- pozszam(L, 0, P). pozszam([], P, P). pozszam([X|L], P0, P):- X > 0, P1 is P0+1, pozszam(L, P1, P). pozszam([X|L], P0, P):- X =< 0, pozszam(L, P0, P). 4. Írjon olyan Prolog eljárást, amely egy adott atomból kivág egy adott pozición kezdődő, adott hosszúságú rész-atomot! Az eljárás hiúsuljon meg, ha ez nem lehetséges! % sub_atom(Atom, Index, Hossz, Részatom): Az Atom atom Index pozicióján % kezdődő és Hossz hosszúságú része a Részatom. % :- pred sub_atom(atom::in, int::in, int::in, atom::out). | ?- sub_atom(akolbolint, 3, 5, S). S = olbol | ?- sub_atom(akol, 3, 5, S). no 5. Írjon olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezésben szereplő számok listáját állítja elő, a sorrend és a többszörös előfordulások megtartásával. Vigyázat: a kifejezésben változók is előfordulhatnak! Törekedjék hatékony megoldásra, kerülje az append eljárás használatát! % szamok(Kif, L): L a Kif kifejezésben szereplő számok listája. % :- pred szamok(univ::in, list(int)::out). Példák: | ?- szamok(1+2*3/4, L). L = [1,2,3,4] | ?- szamok(1+2*f(X,2,g(1)), L). L = [1,2,2,1] Megoldás: szamok(Kif, L) :- szamok(Kif, [], L). szamok(Kif, L, L) :- var(Kif), !. szamok(Kif, L, [Kif|L]) :- number(Kif), !. szamok([K|KL], L0, L) :- !, szamok(KL, L0, L1), szamok(K, L1, L). szamok(Kif, L0, L) :- compound(Kif), !, Kif =.. [_|KifL], szamok(KifL, L0, L). szamok(Kif, L, L) :- atom(Kif). =========================================================================== A megoldásokban segédeljárásként használhatja a Prolog jegyzetben definiált eljárásokat (de csak ezeket). 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(750615))? Indokolja meg miért! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, NL), sort(NL, [H|_]), append(_, [E,H|_], NL), !, put(E), nl. p(_) :- write('nem megy'), nl. Megoldás: p(N) először kiírja N értékét, és egy újsort. Felbontja N-et számjegyei kódlistájára, majd megállapítja a legkisebb (kód)értékű számjegyet (a 'sort' beépített eljárással). Az 'append' eljárás segítségével ezután megkeresi a legkisebb számjegy legelső, nem számeleji előfordulását, és kiírja az ezt megelőző számjegyet. Ha a legkisebb számjegy csak a szám első jegyeként fordul elő, kiírja a 'nem megy' szöveget. (Ez utóbbi eset, helyesen képzett dátum esetén gyakorlatilag nem fordulhat elő.) Példák: | ?- p(751201). 751201 2 | ?- p(731121). 731121 3 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. Feltételezzük, hogy a lists könyvtár be van töltve. a. ?- X =:= 7//3. b. ?- X is 2*3, X == 3*2. c. ?- name(haho, [A|U]), reverse(U, R), name(X, [A|R]). d. ?- append(X, [1|U], [3,2,1]). e. ?- length(X, 1), arg(1, X, 2). f. ?- 1+2*3 =.. [F|X]. Megoldás: Válasz: a. hiba b. meghiúsulás c. siker, X = hoha d. siker, X = [3,2] (U = []) e. siker, X = [2] f. siker, X = [1,2*3] (U = +) 3. Írjon Prolog eljárást az olyan háromjegyű decimális számok felsorolására, amelyek minden jegye prím (azaz a 2 3 5 7 jegyek valamelyike) és a szám osztható mindegyik számjegyével. % primoszt(S): S háromjegyű decimális szám, amelynek mindegyik jegye % prím és S osztható mindegyik jegyével % :- pred primoszt(int::out). Megoldás: primoszt(S) :- primjegy(A), primjegy(B), primjegy(C), S is A*100+B*10+C, S mod A =:= 0, S mod B =:= 0, S mod C =:= 0. primjegy(2). primjegy(3). primjegy(5). primjegy(7). 4. Írjon olyan Prolog eljárást, amely egy adott atomban keres egy abban előforduló legalább kétkarakteres palindromot, és megadja ennek kezdő indexpozicióját (1-től számozva)! Visszalépéskor legyen hajlandó az összes ilyen részatomot felsorolni! Palindromnak hívunk egy olyan jelsorozatot, amely visszafelé olvasva önmagát adja. % palindex(Atom, Palindrom, Index): Az Atom atomban az Index % kezdőpozición a Palindrom részatom áll, amely egy legalább két % karakterből álló palindrom. % :- pred palindex(atom::in, atom::out, int::out). Példa: | ?- palindex(balalajka, P, I). I = 2, P = ala ? ; I = 2, P = alala ? ; I = 3, P = lal ? ; I = 4, P = ala ? ; no Megoldás: palindex(Atom, Palindrom, Index) :- name(Atom, Chars), append(C1, C2, Chars), PChars = [_,_|_], append(PChars, _, C2), reverse(PChars, PChars), length(C1, L), name(Palindrom, PChars), Index is L+1. 5. Írjon olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezésnek, mint fastruktúrának előállítja a tükörképét, azaz a struktúra argumentumait fordított sorrendbe állítja és minden argumentumot is tükröz. Vigyázat: a kifejezésben változók is előfordulhatnak! % tukre(Kif, Tukor): A Kif Prolog kifejezés tükörképe Tukor. % :- pred tukre(univ::in, univ::out) Példa: | ?- tukre(f(1,2,g(a,b,c),A-6), Tukor). Tukor = f(6-A,g(c,b,a),2,1) ? Bónusz-kérdés: milyen eredményt ad az alábbi hívás: | ?- tukre([1,2,3], Tukor). Megoldás: tukre(Kif, Kif) :- var(Kif), !. tukre(Kif, Ford) :- Kif =.. [M|AL], listatukre(AL, [], FL), Ford =.. [M|FL]. listatukre([], FL, FL). listatukre([K|KL], FL0, FL) :- tukre(K, F), listatukre(KL, [F|FL0], FL). Bónusz-kérdésre a válasz: Tukor = [[[[]|3]|2]|1] ? =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(770615))? Indokolja meg miért (írja le általánosan mit csinál az eljárás)! :- use_module(library(lists)). % :- pred p(int::in). p(N):- write(N), nl, name(N, NL), append(_, [A,B|L], NL), ( A mod 2 =:= B mod 2 -> true ; L = [] ), put(A), put(B), nl, L = []. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- X == 20/3+1. b. ?- name(273, [U,V|_]), X is V-U. c. ?- append(X, [_,_], [a,b,c]). d. ?- f(a,b) =.. [_|L], X =.. L. e. ?- X =:= 6//(1+2), atomic(X). f. ?- .(_,X) = [3,2,1]. 3. Egy számlistában emelkedőnek hívunk egy olyan, legalább háromelemű folytonos részlistát, amely szigorúan monoton növekedő, és egyik irányban sem terjeszthető ki szigorúan monoton módon. Írjon olyan Prolog eljárást, amely felsorolja egy adott számlistában levő emelkedőket! % emelkedo(L, EL): Az L számlistának folytonos része az EL emelkedő. % :- pred emelkedo(list(int)::in, list(int)::out). | ?- emelkedo([1,2,-1,-2,5,8,9,3,4,2,4,6,7,6,5,4], EL). EL = [-2,5,8,9] ? ; EL = [2,4,6,7] ? ; Segítség: Javasoljuk a következő segédeljárás definiálását: % mon_kezdo(L, MF, ML): Az L számlista maximális szigorúan monoton növő % kezdőszelete MF, ez utáni maradék-listája ML. % :- pred mon_kezdo(list(int)::in, list(int)::out, list(int)::out). | ?- mon_kezdo([2,3,1,2], MF, ML). MF = [2,3], ML = [1,2] ? 4. Írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezésből kigyűjti a benne előforduló atomokat, és előfordulásaik számával párba állítva egy listát képez ezekből! A struktúra-névként való előfordulásokat ne számítsa be! Vigyázat: a kifejezésben változók is előfordulhatnak! % eloford(Kif, Elof): Elof `atom-dbszám' alakú párok listája, ahol `atom' a % Kif tetszőleges kifejezésben előforduló atom, és `dbszám' az `atom' Kif-beli % előfordulásainak száma. % :- type atomszam ---> atom-int. % :- pred eloford(univ::in, list(atomszam)::out). | ?- elof(beta+alfa*(beta+beta), EL). EL = [beta-3,alfa-1] ? | ?- elof(f(g, h(f,g,23), X, h), EL). EL = [h-1,g-2,f-1] ? Könnyített feladat: Felteheti, hogy a kifejezésben csak a + és * kétargumentumú struktúrák szerepelnek, mint az első példában. =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát, illetve ha a 760713 számot adja meg (pl ?-p(760713))? Indokolja meg miért (írja le általánosan mit csinál az eljárás)! :- use_module(library(lists)). % :- pred p(int::in). p(N):- write(N), nl, name(N, [_,A|NL]), append(L, [B|_], NL), name(AB, [A,B]), ( L = [] ; AB mod 3 =:= 0 ), write(AB), nl, fail. p(_). 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- functor(f*g+h, X, _). b. ?- member(X, [1,2,3]), !, X>2. c. ?- append(X, [b|_U], [a,a,b,c,d]). d. ?- X is 8//3, 3*X @> X*3. e. ?- Y = [], X is [], X==Y. f. ?- findall(U, (between(1,3,V),U is V mod 2), X). 3. Írjon olyan Prolog eljárást, amely egy atomként megadott Unix állománynevet a benne levő '/' karakterek mentén felbont és az így kapott komponens-atomok listáját adja vissza! Ha az állománynév elején és/vagy végén szerepel '/' jel, akkor a visszaadott lista első és/vagy utolsó eleme legyen az üres atom (''). Vigyázzon arra, hogy az eljárás csak egy megoldást adjon! % komplista(AN, KL): Az AN állománynév komponenseinek listája KL. % :- pred komplista(atom::in, list(atom)::out). | ?- komplista('dr-1/dr-2/file.ext', KL). KL = ['dr-1','dr-2','file.ext'] ; no | ?- komplista('/dr-1/file.ext/', KL). KL = ['','dr-1','file.ext',''] ; no 4. Írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezés esetén felsorolja a benne lévő olyan legbővebb összetett részkifejezéseket, amelyek egész számokból a + és * kétargumentumú operátorokkal épülnek fel! A `legbővebb' jelző azt jelenti, hogy egy ilyen részkifejezés részeit ne sorolja fel, az `összetett' jelző pedig azt, hogy az egyetlen számból álló részkifejezé- seket se sorolja fel. Vigyázat: a kifejezésben változók is előfordulhatnak! % ari_resz(Kif, R): A Kif kifejezés része R, R összetett, egész számokból % a + és * operátorokkal épül fel, és az ilyenek között a legbővebb. % :- pred ari_resz(univ::in, univ::out). | ?- ari_resz(f(1+2, 8, 4+3*X, g(5+4*2)), R). R = 1+2 ; R = 5+4*2 ; no | ?- ari_resz(a+(1+2*3)*X+4*5+6, R). R = 1+2*3 ; R = 4*5 ; no % Megjegyzés: a `...+4*5+6' zárójelezése `(...+4*5)+6', ezért a 4*5+6 ennek % nem részkifejezése. Természetesen a zárojelezéssel nem kell foglalkoznia a % megoldásban, hiszen azt a Prolog beolvasója megteszi! Könnyített feladat: Felteheti, hogy a kifejezésben csak a + és * kétargumentumú struktúranevek szerepelnek, mint a második példában. =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát (pl ?-p(770321))? Indokolja meg miért (írja le általánosan mit csinál az eljárás)! :- use_module(library(lists)). % :- pred p(int::in). p(N):- write(N), nl, name(N, [_|NL]), append(_, [B], NL), member(A, NL), name(AB, [A,B]), (A - B) mod 2 =:= 0, write(AB), nl, fail. p(_). 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- X =:= 7//3. b. ?- a+b =.. X. c. ?- X is 11 mod 3, X is X+1. d. ?- append(X, X, [2,2]). e. ?- X = 3*4+1. f. ?- length(X, 1), arg(1, X, a). 3. Írjon olyan Prolog eljárást, amely egy adott atomban keres egy abban előforduló legalább kétkarakteres olyan folytonos részt, amely csupa kisbetűből áll, és maximális, azaz egyik irányban sem terjeszthető ki kisbetűvel! Az eljárás adja ki a megtalált részatom kezdő indexpozicióját is (1-től számozva)! Visszalépéskor legyen hajlandó az összes ilyen részatomot felsorolni! % szava(Atom, Szo, Index): Az Atom atomban az Index kezdőpozición a Szo % áll, amely csupa kisbetűből álló maximális, legalább kétbetűs atom. % :- pred palindex(atom::in, atom::out, int::out). | ?- szava('a gyogy* 6ott', S, I). I = 3, S = gyogy; I = 11, S = ott; no Könnyített feladat: eltekinthet a maximalitási feltételtől. 4. Írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezésben minden egész számot a kétszeresére cserél! Vigyázat: a kifejezésben változók is előfordulhatnak! % ketszer(Kif, Kif2): A Kif2 kifejezés a Kif olyan másolata, amelyben % minden Kif-beli egész szám helyett annak kétszerese szerepel. % :- pred ketszer(univ::in, univ::out). | ?- ketszer(f(1,X,a,[2,4]), K). K = f(2,X,a,[4,8]) ? | ?- ketszer(1*a+2*3+X, K). K = 2*a+4*6+X ? Könnyített feladat: Felteheti, hogy a kifejezésben csak a + és * kétargumentumú struktúranevek szerepelnek, mint a második példában. =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(770615))? Indokolja meg miért! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, [_,_,_|NL]), append(L, [_], NL), name(M, L), between(M, 100, I), I mod 3 =:= 0, !, write(I), nl. p(_) :- write('nem megy'), nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- Y = [], X is [], X==Y. b. ?- X =.. [f,g,h]. c. ?- X is 5//2+3. d. ?- name(12, X). e. ?- X is 1+2, \+ X = 3. f. ?- X = 14//(2+3), atomic(X). 3. Másodrendű számtani sorozatnak hívunk egy sorozatot, ha szomszédos tagjainak különbsége számtani sorozatot alkot (pl. a négyzetszámok másodrendű számtani sorozatot alkotnak). Írjon olyan Prolog eljárást, amely adott kezdőelem, kezdő-különbség és a különbség-növekmény alapján adott tagszámú másodrendű számtani sorozatot állít elő. % mszamsor(N, X1, D1, DD, L): L egy olyan N elemű másodrendű számtani % sorozat, amelynek első tagja X1, első két tagjának különbsége D1, és % a különbség növekménye DD. Ha N=<0, akkor L=[]. % :- pred mszamsor(int::in, int::in, int::in, list(int)::out). Példa: | ?- mszamsor(10, 0, 1, 2, L). L = [0,1,4,9,16,25,36,49,64,81] 4. Írjon Prologban egy olyan eljárást, amely egy tetszőleges Prolog struktúra- kifejezés összes olyan valódi részstruktúráját felsorolja, amelynek neve megegyezik az egész kifejezés nevével. Nem számít valódi részstruktúrának maga az egész kifejezés, és a benne előforduló atomok. Vigyázat, a kifejezésben változók is előfordulhatnak! % nevu_resze(Kif, Resz): Resz a Kif-nek olyan valódi részstruktúrája, % amelynek neve megegyezik Kif nevével. % :- pred nevu_resze(any::in, any::out). Példa: | ?- nevu_resze(f(1,f(2), f(f(X)), g(f)), R). R = f(2); R = f(f(X)); R = f(X) 5. írjon egy olyan Prolog eljárást, amely visszaadja egy atom formájában megadott szövegben a szavak számát. Szónak számít minden 32-nél nagyobb ASCII kódú karakterekből álló összefüggő jelsorozat. A szavakat egy vagy több láthatatlan (32-nél kisebb-egyenlő kódú) karakter választja el. A szöveg elején és végén előfordulhatnak láthatatlan karakterek. Törekedjék hatékony (jobbrekurzív) megoldásra. % szoszam(Atom, Szam): Szam az Atomban előforduló szavak száma. % :- pred szoszam(atom::in, int::out). Példa: | ?- szoszam(' Ali baba és a 40 rabló', N). N = 6 =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(770615))? Indokolja meg miért (írja le szövegesen az alkalmazott algoritmust)! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, NL), reverse(NL, [_,A|_]), member(X, [A|NL]), X < 0'3, put(X), fail. p(_N) :- nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- functor(a+1,X,_). b. ?- X is 2*4, compound(X). c. ?- X =:= 7//3+1. d. ?- X = 1+2, X \== 3. e. ?- X is 10 mod 3, X is X+1. f. ?- append(X, [_,_], [9,8,7]). 3. Egy [a1,..., an] lista összeg-listájának hívjuk az [s1,...,sn] listát, ahol si = a1+...+ai, i=1,...,n. Írjon olyan Prolog eljárást, amely adott számlista összeg-listáját állítja elő! % osszlista(L, SL): L összeg-listája SL. % :- pred osszlista(list(int)::in, list(int)::out). | ?- osszlista([1,2,3,4], L). L = [1,3,6,10] 4. Egy számlistában kaptatónak hívunk egy olyan legalább kételemű folyamatos részlistát, amely szigorúan monoton növő, és egyik irányba sem terjeszthető ki szigorúan monoton módon. Írjon olyan Prolog eljárást, amely felsorolja egészek egy adott listájában található kaptatókat. % kaptato(L, K): K az L számlistában előforduló kaptató, azaz maximális % szigorúan monoton növő, legalább kételemű folytonos részlista. % :- pred kaptato(list(int)::in, list(int)::out). | ?- kaptato([1,2,3,3,1,3,5,4,3,2,4], L). L = [1,2,3]; L = [1,3,5]; L = [2,4] 5. Írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog kifejezésből listába gyűjti a benne előforduló egész számokat! Az előfordulások sorrendjét őrizze meg! Vigyázat, a kifejezésben változók is előfordulhatnak! % szamai(Kif, EL): EL a Kif-ben előforduló egész számok listája. % :- pred szamai(any::in, list(int)::out). | ?- szamai(f(5,2+5,g(0)), L). L = [5,2,5,0] =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(770615))? Indokolja meg miért (írja le szövegesen az alkalmazott algoritmust)! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, [_|L]), L1=[_|_], append(L1, [C,_|_], L), name(N1, L1), D is C-0'0, I is N1+D, write(I), nl, fail. p(_). 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- [a,b] =.. X. b. ?- member(X,[3,2,1]), !, X<2. c. ?- name(12+3, X). d. ?- X = f(Z,Z), arg(2, X, 1). e. ?- X is 10//3, 2*X @< X*2. f. ?- findall(U, (between(1,3,V),U is V*V), X). 3. Egy [a1,..., an] sorozat ellenőrző összegeként gyakran használják az `(1*a1+2*a2+...+n*an) mod (n+1)' kifejezést. Írjon olyan Prolog eljárást, amely adott számlista fenti ellenőrző összegét állítja elő! % ellossz(L, EO): Az L számlista fenti ellenőrző összege EO. % :- pred osszlista(list(int)::in, int::out). | ?- ellossz([6,3,2], EO). EO = 2 (mert (1*6+2*3+3*2) mod 4 = 18 mod 4 = 2) 4. Írjon olyan Prolog eljárást, amely egy egyváltozós kifejezés adott helyen vett behelyettesítési értékét számítja. A kifejezést egy olyan Prolog adatstruktúrával adjuk meg, amely az `x' névkonstansból és számokból a `+', `-' és `*' kétargumentumú operátorokkal épül fel. % erteke(Kif, X, Ert): A Kif kifejezés értéke az x=X helyen Ert. % :- pred erteke(univ::in, int::in, int::out). Pluszfeladat: Oldja meg a fenti feladatot úgy, hogy megenged minden, az `is' beépített eljárás által kezelt egy- ill. kétargumentumú műveletet. | ?- erteke((x+1)*(x+1)-2*(x+1)+1, 4, E). E = 16 5. Írjon egy olyan Prolog eljárást, amely egy tetszőleges Prolog névkonstans (atom) esetén felsorolja a benne előforduló egész számokat. Pontosabban: az eljárás megkeresi a névkonstanst alkotó karakterlista egy olyan folytonos részét, amely csupa számjegyből áll és egyik irányba sem terjeszthető ki számjeggyel. Visszaadja a számjegysorozat decimális számként vett értékét, visszalépéskor felsorolva az összes ilyen számot. % nevszam(Atom, E): E az Atom-ban előforduló egész szám. % :- pred nevszam(atom::in, int::out). | ?- nevszam('123 abc345-6', Sz). Sz = 123; Sz = 345; Sz = 6; no =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(770615))? Indokolja meg miért (írja le szövegesen az alkalmazott algoritmust)! :- use_module(library(lists)). % :- pred p(int::in). p(N) :- write(N), nl, name(N, [_|L]), append(_, [C1,C2|L1], L), C1 < C2, !, name(N1, L1), write(N1), nl. p(_) :- write('nem megy'), nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg az X változó értékét. Mindegyik célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke. a. ?- X is +(2,5), X =:= 20//3 b. ?- name(X, [0'0,0'2,0'8]). c. ?- findall(V, (member(V,[9,8,0,2,0,2]), V>1), X). d. ?- functor(X, f, 0). e. ?- X =:= 12//(3+2), atomic(X). f. ?- append(X, [2|U], [3,2,1]). 3. Nevezzük egy x[1],..., x[n] sorozat `önszorzatának' a `x[1]*x[2]+...+x[n-1]*x[n]' kifejezést (n >= 2). Írjon olyan Prolog eljárást, amely adott számlista önszorzatát állítja elő! % onszorzat(L, Sz): Az L legalább kételemű számlista fenti önszorzata Sz. % :- pred onszorzat(list(int)::in, int::out). | ?- onszorzat([1,2,3,4], S). S = 20 4. Egy számlistában fordulónak hívunk egy olyan belső elemet, amely vagy kisebb mind az őt közvetlenül megelőző, mind az őt közvetlenül követő elemnél, vagy mindkettőnél nagyobb. Írjon olyan Prolog eljárást, amely egy számlistából előállítja a benne levő forduló-elemek listáját, a sorrend megőrzésével! % forduloi(L, ML): Az L számlista forduló-elemeinek listája ML. % :- pred forduloi(list(int)::in, list(int)::out). | ?- forduloi([1,2,4,1,2,5,3], L). L = [4,1,5] 5. Egy irányítatlan gráfot az élei listájával adjuk meg, egy élet a két végpontnak a '-' operátorjellel való összekapcsolásával jelölünk (a két végpont sorrendje tetszőleges). A végpontokat Prolog atomok jelölik. Írjon egy olyan Prolog eljárást, amely egy gráfban köröket keres! A kört azt általa sorra érintett csúcspontok listájával ábrázoljuk, a lista első elemét nevezzük a kör kezdőpontjának. Az eljárás adott gráf és adott kezdőpont esetén sorolja fel az adott pontban kezdődő köröket! Gondoskodjék róla, hogy ugyanannak a körnek a kétféle irányú bejárásából keletkező két lista közül az eljárás csak az egyiket sorolja fel! (Az alábbi példában pl. az [a,b,c,d] és [a,d,c,b] közül csak az egyiket.) % kore(G, P, K): A G gráfban K egy P kezdőpontú kör. a --- b % :- type pont == atom. :- type el ---> pont-pont. | \ | % :- type graf == list(el). :- type kor == list(pont). | \ | % :- pred kore(graf::in, pont::in, kor::out). | \ | d --- c | ?- kore([a-b,a-c,a-d,b-c,c-d], a, K). K = [a,b,c]; K = [a,b,c,d]; K = [a,c,d]; no =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(740513)). p(N):- write(N), nl, name(N, NL), append(_, [A, B|_], NL), B mod 2 =:= 0, put(A), fail. p(N):- nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg X értékét. a. ?- X is 1+2, !, X > 3 ; X = 2. b. ?- X = 5//2. c. ?- X =:= 3*4. d. ?- X is [1,2]. e. ?- \+ X == 1. f. ?- 1+2 =.. X. 3. Írjon Prologban egy eljárást, amely két, nem feltétlenül egyforma hosszú lista elemeit összefésüli. Vigyázzon, hogy többszörös megoldások ne fordulhassanak elő! % kever(+L1, +L2, ?L): L1 és L2 listákelemeinek osszefésülése L. Példák: ?- kever([a,b,c],[x,y,z], KL). válasz: KL = [a,x,b,y,c,z] ?- kever([a,b,c],[z], KL). válasz: KL = [a,z,b,c] ?- kever([a,b],[x,y,z], KL). válasz: KL = [a,x,b,y,z] 4. Írjon Prologban egy eljárást, amely egy tetszőleges Prolog kifejezésben minden számot eggyel nagyobbra cserél. Vigyázat: a kifejezésben változók is előfordulhatnak! % novel(+Kif, ?Kif1): Kif1 ugyanolyan Prolog kifejezés mint Kif, csak % minden szám helyett az eggyel nagyobb szám szerepel benne. Példa: ?- novel(f(1, X, 2, [3,4]), Kif1). válasz: Kif1 = f(2, X, 3, [4,5]) 5. Írjon Prologban egy számlista harmonikus közepének kiszámítására szolgáló eljárást. Használjon jobbrekurziót. % harmonikus(+SzL, ?HK): HK az SzL számlista harmonikus közepe. (a_1, ..., a_n számok harmonikus közepe az n/(1/a_1+...+1/a_n)). Példa: ?- harmonikus([2,4,4], H). valasz: H = 3 =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(740613)). p(N):- write(N), nl, name(N, [_,_|NL]), select(NL, A, NL1), member(B, NL1), (A+B) mod 2 =:= 1, !, put(A), put(B), nl. p(_):- write('nem megy'), nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg X értékét. (A célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke.) a. ?- X = 7//3. b. ?- X == 3*4. c. ?- 4*3 is X. d. ?- name(789, [Y|_]), X is Y-0'0. e. ?- \+ X = 1, !, X = 2 ; X = 3. f. ?- [1,2] =.. [X|_]. 3. Írjon Prologban egy eljárást, amely névkonstansok egy listáját összefűzi egyetlen névvé. Törekedjen hatékony jobbrekurzív megoldásra! % nevf(+NevL, ?OsszNev): OsszNev a NevL névlista összefűzésével áll elő. Példa: ?- nevf([ab, ba, hagy], Ossz). válasz: Ossz = abbahagy. 4. Írjon Prologban egy lista maximális elemének meghatározására szolgáló eljárást. A listelemek összehasonlítására szolgáló kétargumentumú reláció nevét az eljárás paraméterként kapja. Használjon jobbrekurziót. % listamax(+L, +KisebbRel, ?M): Az L nem-üres lista KisebbRel szerinti % legnagyobb eleme M. Példa: legyen a kr reláció definiciója: kr(_-X, _-Y):- X < Y. Ekkor: ?- listamax([alfa-3,beta-5,gamma-1], kr, M). válasz: M = beta-5 5. A G irányítatlan gráfot az élek listájával adjuk meg, egy élet a két végpontnak a '-' operátorjellel való összekapcsolásával jelölünk (a két végpont sorrendje tetszőleges). A végpontokat Prolog konstansok jelölik. Pl az [a-b,b-c,c-a] lista az abc háromszöget jelöli. Írjon egy olyan Prolog eljárást, amely megállapítja egy ily módon adott gráf pontjainak fokszámát. (A gráf egy pontjának fokszáma a belőle kiinduló élek száma.) Használjon jobbrekurziót. % fokszamai(+G, ?FL): A G gráf pontjainak fokszámát az FL lista írja le, % amelynek elemei Pont-Fokszám alakú párok. A gráf minden pontja pontosan % egyszer szerepel FL-ben. Az FL lista elemeinek sorrendja érdektelen. Példa: ?- fokszamai([a-b,b-d,c-b], FL). válasz: FL = [a-1,b-3,d-1,c-1]. =========================================================================== 1. Mit ír ki az alábbi p eljárás, ha hívásakor paraméterként az Ön hatjegyű (EEHHNN alaku) születési dátumát adja meg (pl ?-p(740613)). p(N):- write(N), nl, name(N, NL), append(_, [A,B|_], NL), name(AB, [A,B]), AB mod 3 =:= 0, !, write(AB), nl. p(_):- write('nem megy'), nl. 2. Írja mindegyik Prolog cél mellé annak futási eredményét (siker, meghiúsulás, vagy hiba). Sikeres futás esetén adja meg X értékét. (A célt a Prolog interpreternek önmagában adjuk oda, azaz futásának kezdetén a célban előforduló változóknak nincs értéke.) a. ?- X =:= 7//3. b. ?- X is 3*4. c. ?- 4*3 == 3*4. d. ?- X =.. [a,b,c]. e. ?- bagof(N, between(1,3,N), X). f. ?- X = 1*2, atomic(X). 3. Írjon egy erdekes(X) Prolog eljárást, amely felsorolja a következő tulajdonsággal bíró X számokat: X tizes számrendszerbeli alakja AB. Ha X-et megszorozzuk azon Y számmal, amelynek tizes számrendszerbeli alakja BA, akkor eredményül egy ACA alakú háromjegyű számot kapunk. 4. Írjon egy Prolog eljárást, amely egy tetszőleges Prolog névkonstansból kiválasztja a nagybetűket, és az ezekből álló nevet adja vissza. % nagybetui(+Nev, ?Nagy): Nagy a Nev nev nagybetűiből álló név. Példa: ?- nagybetui('ali BabA Lova', X). válasz: X = 'BAL' 5. a. Írjon egy Prolog eljárást, amely két azonos hosszúságú szamlista elemenként vett összegét képzi: % listaosszeg(+L1, +L2, ?L3): Az L3 lista az L1 és L2 elemenként vett összege b. Altalanositsa ezt az eljarast egy olyan eljarassa, amely tetszoleges szamu azonos hosszúságú szamlista osszeget kepzi: % listaosszeg(+LL, OL): LL csupa azonos hosszusagu szamlista listaja. OL % ezek elmenkent vett osszege. Példák: ?- listaosszeg([1,2,3], [4,5,6], L). válasz: L = [5,7,9]. ?- listaosszeg([[1,2,3], [4,5,6], [7,8,9]], L). válasz: L = [12,15,18].