Conversia vector-matrice in Prolog
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Impachetarea unei liste in liste de liste (Conversia vector-matrice)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Iosif Chelu, an III-ZI, 2009.
% Facultatea de Matematica si Informatica, Universitatea Spiru Haret Bucuresti.
% http://fmi.spiruharet.ro/bodorin/aicl.html
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Prolog, TP 2.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PREDICATES
lconcat(lr,lr,lr)
llrev(llr,llr)
llrev(llr,llr,llr)
imp(lr,r,llr)
imp(lr,r,r,lr,llr,llr)
CLAUSES
lconcat([],L,L).
lconcat([H|T],L,[H|R]):-lconcat(T,L,R).
% oglindirea unei liste de liste
% e la fel ca cea de la liste; se putea folosi aceeasi dar cu alte
llrev(L,R):-llrev(L,[],R).
llrev([],R,R).
llrev([H|T],Ri,R):-llrev(T,[H|Ri],R).
%------------------------------------------------------------------
% Impachetarea listei de liste (in blocuri de dimensiuni egale)
% "lista de impachetat" , "marimea blocurilor" , "rezultatul"
imp(L,N,R):-imp(L,N,0,[],[],Ri),llrev(Ri,R).
% Inceperea cautarii.
% !!!!! pntru o mai usoara intelegere este recomandata citirea predicatelor, dupa acesta, incepand cu ultimul si terminand cu al doilea.
% Ca sa gasim rezultatul impachetarii listei L in liste de N elemente in variabila R, cautam rezultatul impachetarii lui L in liste "mici" de
% N elemente formand, pe rand, cate o lista "mica"( prima pereche [] - o lista vida la care se vor adauga elemente ) de N elemente care
% de fiecare data incepe cu 0 elemente. Aceste liste, pe rand se adauga la lista de liste ( a doua pereche [] - o lista de liste vida la care
% se vor adauga liste) care, in fnal, este rezultatul cautat. Acest rezultat, la finalul rularii, se pune in Ri care este lista de liste avand
% elementele ( liste ) ordonate de la coada la cap. Astfel se oglindeste acest rezultat in R, rezultatul cautat.
imp([],N,N,_,R,R):-!.
% Caz de oprire a cautarii; ultima lista "mica" s-a adaugat la lista de liste
% Atunci cand lista din care se iau elemente ( [] ) ajunge vida iar ultima lista "mica" formata a avut N elemente ( al doilea N )
% inseamna ca am ajuns la sfarsitul cautarii si se pune lista de liste gasita ( primul R ) in rezultat ( al doilea R ).
imp([],N,_,L1,Ri,R):-lrev(L1,L2),imp([],N,N,[],[L2|Ri],R),!.
% Caz in care lista "mica" e gta de pus in lista de liste dar nu are N elemente
% Atunci cand lista din care se iau elemente ( [] ) ajunge vida iar ultima lista "mica" formata ( L1 ) nu a avut N elemente ( _ - adica orice
% numar de elemente ) atunci se oglindeste aceasta lista formata ( L1 ) in L2 ( deoarece are elementele ordonate de la coada la cap ) si se
% adauga la lista de liste in formare ( Ri ), iar numarul de elemente al listei "mici" e considerat N pentru a indica terminarea cautarii.
imp(L,N,N,L1,Ri,R):-lrev(L1,L2),imp(L,N,0,[],[L2|Ri],R),!.
% Caz in care lista "mica" e gata de pus in lista de liste.
% Atunci cand avem elemente in lista din care formam rezultatul ( L ) iar lista "mica" formata are N elemente, atunci se adauga
% aceasta lista "mica" ( se oglindeste apoi se adauga oglinditul ) la lista de liste care se formeaza ( Ri ) si se continua cautarea pentru
% o lista "mica" vida ( [] ), la care se vor adauga elemente, care are 0 elemente.
imp([H|T],N,Ni,L1,Ri,R):-Nia=Ni+1,imp(T,N,Nia,[H|L1],Ri,R).
% Caz general: Adaugarea unui element la lista "mica".
% Atunci cand avem elemente in lista din care formam rezultatul ( [H|T] ) iar lista "mica" ( L1 ) in curs de formare nu are inca N
% elemente ( are Ni elemente ), adaugam primul element din lista din care formam rezultatul ( H ) la lista "mica" ( L1 ), incrementam
% contorul ( Nia ) care memoreaza numarul de elemente din lista "mica" si cautam in continuare elemente in ce a ramas ( T ) din
% lista din care formam rezultatul.