Program Integration(input,output);

{  Himpelsoft 08.03.89                                             }
{                                                                  }
{  Demonstriert Prozedur- und Funktionsparameter sowie Stringtypen }
{                                                                  }
{  Es werden die Quadratfunktion nach dem Trapezsummen- und die    }
{  Sinusfunktion nach dem Simpsonverfahren in wählbaren Grenzen    }
{  integriert.                                                     }

Type string20=array[1..20] of char;

Function g(x:real):real;
  { "Sqr" kann nicht direkt als Parameter übergeben werden.
    Grund: Der Ergebnistyp ist nicht definiert, sondern hängt vom
    Parametertyp ab (integer oder real). Dies gilt auch z. B. für
    "succ" und "pred". Solche speziallen Funktionen sind nicht als
    aktuelle Parameter erlaubt.                                    }

  Begin
    g:=sqr(x)
  End;

Procedure trap(Function f(x:real):real; a,b:real; n:integer; Var erg:real);
  Var s,h:real; i:integer;
  Begin
    h:=(b-a)/n;
    s:=0;
    For i:=1 to n-1 do
      s:=s+f(a+i*h);
    erg:=(0.5*(f(a)+f(b))+s)/n
  End;

Procedure simp(Function f(x:real):real; a,b:real; n:integer; Var erg:real);
  Var t1,t2:real;
  Begin
    trap(f,a,b,n,  t1); { Beachte: eine Function, die "simp" als Parameter }
    trap(f,a,b,2*n,t2); { übergeben wurde, wird hier an "trap" weitergereicht. }
    erg:=(4*t2-t1)/3
  End;

Procedure Tabelle
   ( funk, verf:          string20;
     Function f(y:real):  real;
     Procedure int
       ( function f(y:real): real;
         x1,x2:              real;
         a:                  integer;
         Var                 r:real
       )
   );

  { Man beachte die tolle Schachtelung: Der Prozedurparameter "int" hat
    selbst wieder einen Funktionsparameter! }

  Var lo,hi,e:real; i,max:1..100;

  Begin
    writeln("Integral der Funktion f(x)=",funk);
    writeln;
    write('Grenzen: ');readln(lo,hi);
    write('Anzahl:  ');readln(max);
    page;
    writeln('Integration von f(x)=',funk,' durch ',verf,'verfahren');
    writeln;
    For i:=1 to max do
      Begin
        int(f,lo,hi,i,e);
        writeln(i:8,'   ',e)
      End;
    writeln
  End;

Begin  { Hauptprogramm }
  Tabelle('x^2',   'Trapez' ,g,   trap);
  Tabelle("sin(x)","Simpson", sin,simp)
End.
