Az egyetemen ( PTE TTK Programtervező informatikus ) többek között prolog kurzust is felvettem. Inkább csak érdekességként, így nem merültem el mélyebben a témában, de néhány gyakorló feladatot megosztanék a nagyközönséggel is. Hosszú magyarázatot nem mellékelek, mivel már régen tanultam, és talán nem is tudnék részletesen magyarázni. Azért a fent linkelt wikipédián kívül még egy hasznos oldal: Link
Egy lista elemeinek száma
%üres lista hossza 0
length1([],0).
%egy lista hossza, ami több mint egy elemet tartalmaz,
%és mindegy mi az első eleme,
length1([_|Y],Z):-
%pont olyan hosszú, mint az első elemét leszámítva a többi elemének száma,
length1(Y,V),
%plusz az első elem
Z is V+1.
Lista hosszának fele
%egy lista hosszának fele
length2([X|Y],U):-
%a lista teljes hossza
length1([X|Y],Z),
%és a teljes hossz egyszerűen osztva kettővel
U is Z / 2.
Modulo számítás
%A mod B pontosan A
modulo(A,B,A):-
%ha A már eleve kisebb, mint B
A<B,
%és ekkor már biztos hogy nem kell a többi illeszkedést vizsgálni. Kiléphetünk a ! jellel.
!.
modulo(A,B,X):-
C is A-B, modulo(C,B,X).
Minden egymást követő két elem felcserélése egymással
%üres lista elemeinek cseréje ugyanúgy üres listát ad
pcsere([],[]).
%egy egy elemű lista elemeinek felcserélése ugyanazt az egy elemet adja
pcsere([X],[X]):-
%és ha csak egy elem maradt, akkor kilépünk a keresésből
%mert másképp felajánlaná hogy keres tovább a következő szabály szerint
!.
%Egy legalább 2 elemű lista elemeinek cseréje
pcsere([X,Y|Z],[X2,Y2|Z2]):-
%az első két elem felcserélése
X2 is Y, Y2 is X,
%majd a maradék elem cseréje rekurzív hívással
pcsere(Z,Z2).
Egy lista első eleme
%üres lista első eleme egy üres lista
eleje([],[]).
%egy legalább egy elemű lista első eleme az első elem, és a vége mindegy mi
eleje([X|_],X).
Egy lista utolsó eleme
%egy üres lista utolsó eleme egy üres lista
vege([],[]).
%Egy egy elemű lista utolsó eleme az egyetlen eleme
vege([Y],Y).
%egy több mint egy elemű lista utolsó eleme
vege([_|Y],Z):-
%a lista farkának utolsó eleme rekurzívan keresve
vege(Y,Z),
% majd pedig megszakítjuk a keresést, mert visszaugrana az első szabályra
!.
Egy lista első és utolsó eleme
%üres lista esetén mindkettő üres lista
elejevege([],[],[]).
%egy nem üres lista első és utolsó eleme
elejevege([X|Y],V,Z):-
%az első eleme
eleje([X|Y],V),
%és az utolsó eleme
vege([X|Y],Z),
%és ha megvan, ki kell lépni, hogy ne ugorjon vissza az első szabályra
!.
Lista jobb oldalára fűzés
%----------------------- Jobb oldalra fűzés ---------------------------
%------------- Ez az órai "append" másolata ---------------------------
%üres listához bármit fűzünk, az önmaga lesz
rappend([],L,L).
%ha egy nem üres listához fűzünk hozzá elemet
rappend([X|L1],L2,[X|L3]):-
%az az első lista farka, és a második lista összefűzött változata lesz
rappend(L1,L2,L3).
Lista bal oldalára fűzés
%------------ Ez már ismét saját, az rappend-et felhasználva ----------
%üres listához balról is bármit fűzünk, az önmaga
lappend([],L,L).
%Bármi más listához hozzáfűzni balról annyi,
lappend(L1,L2,L3):-
%mint a második listához jobbról fűzni az elsőt
rappend(L2,L1,L3).
Lista dekrementálása
%üres lista dekrementáltja üres lista
decrList([],[]).
%Egy lista dekrementáltja
decrList(X,Y):-
%ha az valójában csak egy szám
number(X),
%akkor a szám minusz 1
Y is X-1,
%és akkor a lista végén vagyunk, nem kell a következő szabály
!.
%az egy elemű lista dekrementáltja
decrList([X],[Y]):-
%ha az egyetlen eleme egy szám
number(X),
%akkor a szám, minusz 1 elemet tartalmazó egy elemű lista
Y is X-1,
%És mivel ekkor is a lista végén vagyunk, itt sem kell már a következő szabály
!.
%több elemű lista dekrementálja
decrList([X|Y],[X1|Y1]):-
%az első elem dekrementáltja
decrList(X,X1),
%és az összes többi elem dekrementáltja
decrList(Y,Y1),
%ha megvan, akkor nem kérjük újra az első szabályt
!.
Többszintű listák összege
%üres lista hossza 0
sumList([],0).
%egy lista összege, önmaga
sumList(X,X):-
%ha az a lista valójában egy szám
number(X).
%egy nem üres, hosszabb lista összege
sumList([X|Y],Z):-
%az első elemének összege,
sumList(X,S1),
%és a lista farkának összege
sumList(Y,S2),
Z is S1+S2,
%Ha megvan az összeg, nem kérjük az első szabályt újra
!.
Numerikus lista.
%üres lista legyen numerikus lista
isNumericList([]).
%egy elemű lista akkor numerikus,
isNumericList([X]):-
%ha az egyetlen eleme szám
number(X),
%és ha már csak egy elemű lista van, akkor nem kell a többi szabály
!.
%egy több elemű lista akkor numerikus
isNumericList([X|Y]):-
%ha az első eleme szám
number(X),
%és a lista farka numerikus lista
isNumericList(Y).
Lista végigjárása
next1([X|_],X).
%utána a lista farkának
next1([_|X],NEXT):-
%következő elemét vesszük
next1(X,NEXT).
Második paraméter az első paramétert leszámítva megegyezik-e a többivel.
tail([_|L],L).
Az első paraméter benne van-e a listában:
member(X,[X|_]).
%Ha nem az első elem, akkor keressük a lista "farkában".
member(X,[_|L]):-member(X,L).
Lista megfordítása egy lista hozzáfűzésével.
revapp([],L,L).
%Legyen X az első elem, L1 az összes többi. L2 a hozzáfűzendő lista és L3 a megfordított lista.
revapp([X|L1],L2,L3):-
%Önmagát híja rekurzívan, amíg nem tud újra az első szabályra illeszkedni. Ahol L1 üres lista.
%L1 mindig az első paraméter "farka", tehát előbb utóbb üres lesz. A hozzáfűzendő lista pedig
%mindig az aktuális lista első eleme és a végén az előzőleg hozzáfűzött lista.
revapp(L1,[X|L2],L3).
Lista megfordítása
reverse(L,REV):-
%Fűzzük hozzá a listához az üres listát revapp-al. (előző szabály)
revapp(L,[],REV).
A fent leírtak gyakorlatilag szabályok. Amire illeszkedést lehet vizsgálni. Aminek eredménye logikai érték. Ha pedig érték helyett változót adunk meg egy paraméter helyett, akkor megpróbálja az összes lehetséges illeszkedést megkeresni a változóra és feltölti az értékekkel.
A szabályok helyességéért nem tenném tűzbe a kezem, de annak idején tesztelve látszólag jól működtek. Aki a prolog után érdeklődik, a következő oldalról letöltheti az SWI-prolog programot akár windowsra, akár linuxra, de még MacOS-re is: LINK
Hozzászólások
Segítség kérés
Szia most kezdtem tanulnia prologot és szeretnék érdeklődni hogy egy ilyen jellegű feladatot hogy lehetne megvalósítani prologban.
Írjuk meg jobb-rekurziós módon a faktoriálist, és nézzük meg nyomkövetéssel!
2. Faktoriális még másképp -
egy sima rekurziós és egy listás megvalósítása.
A segítséget előre is köszönöm szépen.
Régen volt
Szia. Én nagyon régen nem prologoztam és akkor sem voltam profi. Most nem is érek rá. Majd este ránézek a kérdésedre újra.
De mennyit is tudsz a prologról és melyik részénél akadsz el? Vagy eleve ott, hogy jobb rekurzió hogy oldható meg prologban?