Primerjava prologa in pascala
Iz E-študij, proste zakladnice študentskega znanja
Rešitve treh problemov v Pascalu in Prologu ilustrirajo moč in nemoč Prologa v primerjavi s programskim jezikom Pascal.
- Problem Hanoiskih stolpov pokaže podobnost dveh jezikov pri rekurzivnem programiranju.
- Pri potenčni množici je Prolog superioren zaradi opisnega značaja in fleksibilnejših podatkovnih struktur.
- V množenju matrik se pokaže neprimernost Prologa v numerični matematiki zaradi nezmožnosti spreminjanja vrednosti spremenljivke.
Vsebina |
Hanoiski stolpiči
Imamo tri ploščadi N diskov različnih velikosti. Na začetku so vsi diski na prvi ploščadi urejeni po velikosti, tako da je največji na dnu in najmanjši na vrhuske lahko premikamo iz ploščadi na ploščad drugega za drugimtakoni nikoli večji disk na manjšem. Naloga je poiskati zaporedje premikov tako, da bodona koncu vsi diski na drugi ploščadi.
Program v prologu
/* premakni(pl,p2,p3,N) pomeni premikN diskov izploščadi pl na ploščad p2 */ premakni (_,_,_,0) . premakni(A,B,C,N) :- N > 0, N1 is N - 1, premakni(A,C,B,N1), izpisi_sez(['premakni iz ',A,' na ',B]), nl, premakni(C,B,A,N1).
Program v pascalu
type PLOSCAD = (pl,p2,p3); { za premik N diskov iz ploscadi p1 na ploscad p2 klicemo proceduro PREMAKNI(pl,p2,p3,N) } procedure PREMAKNI(PLA,PLB,PLC:PLOSCAD;N:integer); begin if N > O then begin PREMAKNI(PLA,PLC,PLB,N-1); writeln('premakni iz ploscadi ' PLA,' na ploscad ',PLB); PREMAKNI(PLC,PLB,PLA,N-1) end (* then *) end; (* PREMAKNI *)
Potenčna množica
Program v prologu
potencna([],[[]]). potencna([X|Rep] ,Rezultat) :- potencna(Rep,Potencna), podvoji(X,Potencna,Rezultat). /* za vsako množico iz potenčne množice procedura 'podvoji' doda množicoz dodatnim elementom X */ podvoji(_,[],[]). podvoji(X,[M|Potencna],[M,[XIM]IRezultat]) :- podvoji(X,Potencna,Rezultat).
Program v pascalu
Program je najkrajši, če je analogen programu v prologu. Realizacija s tabelami je dosti bolj zapletena, zato je tu program s seznami, ki ga je tudi lažje primerjati s prologovim programom:
type ELEMENT = record N : integer; NASL : ^ELEMENT end; (* rec *) MNOZICA = ^ELEMENT; POTENCNA = record P : MNOZICA; NASL : ^POTENCNA end; (* rec *) procedure POTENCNA(M : MNOZICA; var PO : POTENCNA); var P1 : POTENCNA; procedure PODVOJI(N : integer; P1 : POTENCNA; var PO : POTENCNA); var PO1, P02 : POTENCNA; M : MNOZICA; begin if P1 = nil then PO := nil else begin (* else *) PODVOJI(N, P1^.NASL, PO1); (* P1.P kaze na izpusceno mn. *) new(P02); new(M); M^.N := N; M^.NASL := P1^.P; (* prikljucimo element mnozici *) P02^.P := M; (* mnozica z elementom N *) P02^.NASL := P01; (* dodamo k trenutni resitvi *) PO^.P := P1^.P; (* mnozica brez elementa N *) PO^.NASL := P02 (* jo dodamo k trenutni resitvi in dobimo rezultat *) end (* else *) end; (* PODVOJI *) begin (* POTENCNA *) if M = nil then begin (* prazna mnozica *) new(PO) ; PO^.P := nil; PO^.NASL := nil end (* then *) else begin (* neprazna mnozica *) POTENCNA(M^.NASL, P1); PODVOJI(M^.N, P1, PO) end (* else *) end; (* POTENCNA *)
Produkt dveh matrik
Izračunaj produkt dveh matrik reda N×N.
Program v prologu
Rešitev s shranjevanjem; vrednosti s procedurama 'assert' in 'retract' je nepregledna in nerodna za prenos rezultata kot argumenta. Zato je tu rešitev s seznami:
/* Matrika je predstavljena s seznamom vrstic,vrstica je seznam števil. Za izračun produkta kliči proceduro: produkt(Matrikal,Matrika2,Produkt,N), N je red matrik */ produkt ([] , _, [] , _) .% ni več vrstic produkt ([VrIOst] ,Matr2, [Vr.prodIOst.prod] ,N) : -prod_vrstice(Vr,Matr2,Vr_prod,N,0), produkt (Ost ,Matr2,Ost.prod,N). /* izračunaj eno vrstico produkta, zadnji argument je števec elementov v vrstici od 1 do N */prod_vrstice(_,_, [] ,N,N) .! . prod_vrstice(Vr,Matr2,[Element lOstalo],N,N1) :-N2 is N1 + 1, prod_elementa(Vr,Matr2,Element,N2),prod_vrstice(Vr,Matr2,Ostalo,N,N2). /* izračunaj en element produkta */ prod_elementa([] , [] ,O,_) . prod_elementa([GllRep],[VrlOstalo],Element,N) :- prod sunianda(G1,Vr,Sumand,N),prod_elementa(Rep,Ostalo,Suma,N), Element is Suma + Sumand. /* izračunaj N-ti sumand elementa produkta */ prod_sumanda(St, [St1Ia ,Sumand,1) :-Sumand is St*Stl, prod_sumanda(St, [_IRep] ,Sumand,N) :-N1isN- 1, prod_sumanda(St,Rep,Sumand,N1).
Program v Pascalu
type MATRIKA = array[1..MAXN,1..MAXN] of real; procedure PRODUKT(M1,M2 : MATRIKA; var P : MATRIKA; N : integer); var VR, ST, EL : integer; begin for VR := 1 to N do for ST := 1 to N do begin P[VR,ST] := 0.0; for EL := 1 to N do P[VR,ST] := P[VR,ST] + M1[VR,EL] * M2[EL,ST] end (* for-for *) end; (* PRODUKT *)