Primerjava prologa in pascala

Iz E-študij, proste zakladnice študentskega znanja

Skoči na: navigacija, iskanje

Rešitve treh problemov v Pascalu in Prologu ilustrirajo moč in nemoč Prologa v primerjavi s programskim jezikom Pascal.

  1. Problem Hanoiskih stolpov pokaže podobnost dveh jezikov pri rekurzivnem programiranju.
  2. Pri potenčni množici je Prolog superioren zaradi opisnega značaja in fleksibilnejših podatkovnih struktur.
  3. 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 *)
Osebna orodja
Imenski prostori
Različice
Dejanja
navigacija

Tiskanje/izvoz
orodja