% ============================================================================= % Deklaratív Programozás 3. gyakorlat, rendezéssel kapcsolatos Prolog eljárások % ============================================================================= /* Feladatok: % rendezett(+L): L (nem feltétlenül szigorúan) monoton növő számlista. % (A "rendezett lista" kifejezés az alábbiakban is nem feltétlenül % szigorúan monoton növekedő listát jelent.) | ?- rendezett([]). yes | ?- rendezett([1]). yes | ?- rendezett([1,2]). yes | ?- rendezett([1,2,2,3]). yes | ?- rendezett([1,22]). yes | ?- rendezett([1,22,3]). no | ?- rendezett([4,1,2,3]). no % releje(+L, -R): Az L számlista maximális nem-üres rendezett % kezdőszelete R. (Determinisztikus.) | ?- releje([], L). no | ?- releje([4,3,1,2,3], L). L = [4] ? ; no | ?- releje([1,2,2,1], L). L = [1,2,2] ? ; no | ?- releje([1], L). L = [1] ? ; no % elso_rresze(L, R): R az L számlista egy folytonos részlistája, mégpedig az első % a maximális, legalább kételemű rendezett folytonos részlisták közül. % (Determinisztikus.) | ?- elso_rresze([4,3,2,1,0], R). no | ?- elso_rresze([4,3,2,1,0,1,0,2,3], R). R = [0,1] ? ; no | ?- elso_rresze([1,0,2,3], R). R = [0,2,3] ? ; no % rresze(L, R): R az L számlista egy olyan folytonos részlistája, amely % legalább kételemű, rendezett és az ilyenek között maximális. % (Nemdeterminisztikus.) | ?- rresze([4,3,2,1,0,1,0,2,3], R). R = [0,1] ? ; R = [0,2,3] ? ; no | ?- rresze([4,5,4,3,2,2,3,1,2,0], R). R = [4,5] ? ; R = [2,2,3] ? ; R = [1,2] ? ; no */ /* Megoldások */ % --------------------------------------------------------------------------- % rendezett(+L): L (nem feltétlenül szigorúan) monoton növő számlista. rendezett([]). rendezett([X|L]) :- rendezett(L, X). % rendezett(+L, +X): [X|L] (nem feltétlenül szigorúan) monoton növő számlista. % Ezen segédeljárás bevezetésével elérhetjük, hogy a Prolog futás során % nem jön létre választási pont (első arg. szerinti indexelést feltételezve). rendezett([], _X). rendezett([Y|L], X) :- X =< Y, rendezett(L, Y). % --------------------------------------------------------------------------- % releje(+L, -R): Az L nem-üres számlista maximális rendezett kezdőszelete R. releje([X|L], R) :- releje(L, X, R). % releje(+L, +X, -R): [X|L] maximális rendezett kezdőszelete R. releje([], X, [X]). releje([Y|L], X, [X|R]) :- ( X =< Y -> releje(L, Y, R) ; R = [] ). % --------------------------------------------------------------------------- % elso_rresze(L, R): R az L számlista egy folytonos részlistája, mégpedig az első % a maximális, legalább kételemű rendezett részlisták közül. elso_rresze(L, R) :- L = [X|L1], ( L1 = [Y|_], X =< Y -> releje(L, R) ; elso_rresze(L1, R) ). % --------------------------------------------------------------------------- % rresze(L, R): R az L számlista egy olyan folytonos részlistája, amely % legalább kételemű, rendezett és az ilyenek között maximális. % Nem a leghatékonyabb megoldás, de a legegyszerűbb, az előző % feladatokra építve. rresze(L, R) :- releje(L, R0), length(R0, N), ( N >= 2, R = R0 ; drop(L, N, L1), rresze(L1, R) ). % drop(L, N, RL) :- sublist(L, 1, N, RL) % (lasd 2. gyak) drop(L, N, RL) :- ( N =:= 0 -> RL = L ; N > 0, L = [_|L1], N1 is N-1, drop(L1, N1, RL) ). :- use_module(library(lists)). % ugyanaz, mint rresze/2, nem hatékony, de deklaratív rresze_dekl(L, R) :- R = [_,_|_], % R legalább kételemű append(E, L1, L), append(R, U, L1), % R részlistája L-nek rendezett(R), % R rendezett R = [R1|_], last(R, Rn), % R = [R1,..., Rn] \+ ( last(E, Em), Em =< R1 ), % R balra nem terjeszthető ki \+ ( U = [U1|_], Rn =< U1 ). % R jobbra nem terjeszthető ki % ugyanaz, mint rresze/2, es hatékony rresze_hatekony(L, R) :- releje_maradek(L, R0, M), ( R0 = [_,_|_], R = R0 ; rresze_hatekony(M, R) ). % releje_maradek(+L, -R, -M): Az L nem-üres számlista maximális rendezett % kezdőszelete R, L fennmaradó része M. releje_maradek([X|L], R, M) :- releje_maradek(L, X, R, M). % releje_maradek(+L, +X, -R, -M): [X|L] maximális rendezett kezdőszelete R, % maradéka M. releje_maradek([], X, [X], []). releje_maradek(L, X, [X|R], M) :- L = [Y|L1], ( X =< Y -> releje_maradek(L1, Y, R, M) ; R = [], M = L ).