Euler

Esistono alcuni linguaggi, non riconducibili ad una stessa famiglia, che hanno nome Euler.

1             Euler (Lisp)

1967? Lisp con sintassi Algol, usato per garfica su IBM 360/30 presso l’università dell’Utah.

2             Euler (Algol)

Euler è una generalizzazione di ALGOL 60 creato da Niklaus Wirth e Helmut Weber nel 1965. Inizialmente fu implementato con NELIAC  (Navy Electronics Laboratory International ALGOL Compiler), su IBM System/360 come microcodice. La versione provata è stata realizzata con Icon  da Thomas W. Christopher del Department of Computer Science and Applied Mathematics dell’Illinois Institute of Technology. 

La versione esaminata si differenzia leggermente da quella prevista da Wirth e Weber, nel senso che estende alcune definizioni ed utilizza dei caratteri ASCII opportuni al posto dei simboli previsti inizialmente, ad esempio invece di utilizza ** per l’elevazione a potenza.

Euler è dinamicamente tipizzato con funzioni per controllare il tipo della variabile e generalizza il concetto di tipo, includendo fra i tipi sia le procedure che le etichette:

·         numeri, con una aritmetica elementare, senza funzioni predefinite

·         booleani

·         reference

·         label oggetto dei goto (W. e W. avevano previsto go to, ma la realizzazione esaminata utilizza una grammatica LL(1))

·         symbol stringhe di caratteri, una implementazione povera, si può solo confrontare per uguale e diverso

·         list (array), gli elementi possono essere misti, numeri o stringhe o array

·         procedure

·         undefined

E’ un linguaggio, in generale, povero di estensioni, tuttavia portatore di nuovi concetti: quali if then else che restituisce un valore o le funzioni utilizzabili come variabili. Originale la dichiarazione di procedure, equiparata ad una assegnazione (<-):

nome <- '[parametri] corpo della procedura';

Le strutture di controllo si basano su if then else e goto, rudimentali l’input/ouput.

L’esempio che segue è una primordiale implementazione di un’addizione Bignum.

(* Euler *)

begin new nList; new rList; new owfl; new i;

  new toChar; new toNum; (* translators functions *)

  label lAdd;

  nList <-(0,9,9,9,9,9,9,9,9,9);

  toNum <- 'formal nL;

            begin new i; label Loop;

            i <- 0;

            Loop:

            i <- i+1;

            out nL[i];

            if i < length nL then goto Loop else "End"

            end';

  rList <- list 10;     (* lista con risultato *)

  i <- length nList;

  owfl <- 0;

  lAdd:

  rList[i] <- 2 * nList[i]+ owfl;

  owfl <-  rList[i] div 10;

  rList[i] <- if rList[i] > 9 then rList[i] - 10 else rList[i];

  i <- i - 1;

  if i > 0 then goto lAdd else out toNum(rList)

end

2.1       Euler G

1970. Estensione grafica, (probabilmente di Euler di Wirth).

3             Euler (Matlab)

Linguaggio per il calcolo numerico

EULER (1999) è un programma interattivo, ispirato a Matlab, per il calcolo numerico, la statistica, l’integrazione con numeri reali e complessi organizzabili in matrici. I risultati sono utilizzabili per produrrre grafici bi e tridimensionali. Euler, inoltre, utilizza Yacas  per il calcolo simbolico.

Per altri tipi di dato Euler è piuttosto rudimentale, accetta stringhe che si possono solamente confrontare o concatenare, possiede tuttavia un interessante tipo complesso intervals: intervalli chiusi numerici: ~a,b~ rappresenta l’intervallo chiuso delimitato dai numeri reali a e b. Gli intervals, sono una struttura su cui possono effettuarsi operazioni aritmetiche ed applicare funzioni (con risultati non sempre, per ragioni di performances, accurati), ma anche operazioni insiemistiche.  Non è molto soddisfacente la gestione delle eccezioni, ad esempio la radice quadrata di un numero negativo provoca un errore, così come l’intersezione di due intervalli disgiunti.

L’input output è semplice, si può leggere o scrivere un file alla volta, ed è finalizzato sostanzialmente ad operare con numeri. L’istruzione getvector(n) tenta di leggere n numeri da un file.

Particolare è l’uso di commenti che, al di fuori di una funzione, sono delimitati, su linee distinte, da comment e endcomment, mentre all’interno di funzioni sono individuati dai caratteri ##.

Le istruzioni condizionali e di controllo, che sono accettate solamente all’interno di una funzione, prevedono una struttura if condizione; else; ... endif;, comprensiva di elseif; condizione; .... Esistono tre costrutti per i cicli:

·         repeat; ...; end;

·         loop a to b; ...; end;   ## # fornisce i vari valori fra a e b

·         for i=a to b [step c;] ...; end;

Come si può notare repeat; è incondinzionato, si esce dal ciclo infinito tramite l’istruzione break.

function GCD(m,n)

  repeat;

    if n > m;     n=n-m;

    elseif m > n; m=m-n;

    else;         break;

    endif;

  end;

  return m;

endfunction

function fnz (funct,x)

 return funct(100,x);

endfunction

>fnz("GCD",250)

           50

>

La gestione delle funzioni è evoluta: Euler supporta la ricorsività, le funzioni possono restituire più valori ed accettare un numero variabile di argomenti, è possibile passare un nome di funzione fra i parametri. I parametri sono passati per referenza (tranne le sottomatrici), sono accettati valori di default. Le variabili dichiarate in una funzione sono locali, il riferimento a variabili esterne va diciarato con global nomevariabile.

 

 

 

Sono presenti funzioni matematiche e trigonometriche basilari, che si applicano a numeri, scalari o matrici, sia reali che complessi; interessante la possibilità di esprimere gli angoli in gradi, tramite l’operatore postfisso °:

>tan(45°)

            1

Sono disponibili diversi costruttori e funzioni su matrici, l’operatore unario postscritto ' (apostrofo) inverte le matrici.

function fnz (x)

return log(x);

endfunction

>simpson("fnz",0.1,5)

       3.3774

Esistono diverse funzioni per integrare funzioni:  simpson, gauss,  romberg, adaptiveint, in ognuna di esse il primo parametro è il nome della funzione da integrare.

L’esempio che segue determina empiricamente le durate ottimali di un semaforo a due vie per minimizzarne i tempi di attesa.  L’algoritmo è vagamente genetico nel senso che dato un insieme di individui i cui "geni" sono i tempi del ciclo del semaforo, è eseguita una simulazione di arrivi con calcolo del tempo totale di attesa. Sono effettuate due simulazioni e ad ogni iterazione sono sostituiti il 10% ed il 20% rispettivamente degli individui che hanno i tempi di attesa superiori alla media.

comment

  This is EULER, Version 3.

endcomment

function IIF(Bool,R1,R2)

  Ret = R2;

  if Bool; Ret = R1; endif;

  return {Ret} ;

endfunction

function Sema(Clk,ActDir,LastChange,TimeS0,TimeS1)

## function Sema return semaphor value, time of changing

## input: Clock, actual semaphor, last time of change, time for every direction

  AS = ActDir;

  LC = LastChange;

  Sx = IIF(ActDir == 0,TimeS0,TimeS1);

  if (Clk > LastChange+Sx)

    AS = mod(ActDir +1,2);

    LC = LastChange + Sx;

  endif

  return {AS,LC}

endfunction

function Main(Generation,Speed)

##  Generation = number of Generation, Speed = sostitution speed (percentage and mean)

SemTime=90;             ## total semaphor time,     

Amt = 2;                ## Arrival Mean Time

People = 100;

History = zeros(Generation,1);     ## Store for value of generation mean

Population = zeros(People,3);   ## array with column Name, time of S0, Wait total

Population(:,1) = (1:1:People)';

Population(:,2) = SemTime*random(People,1);

for ijk = 1 to Generation;

  Population(:,3) = zeros(People,1);

  for ij = 1 to People;

    Clock=0;

    AD=0;

    LC=0;

    S0=Population(ij,2);

    S1=SemTime-S0;

    repeat;

      if Clock > 600; break; endif;

        Clock = Clock + random(1,1) * Amt * 2;

        Direction = IIF(random(1,1) > 0.4,0,1);

        {AD,LC} = Sema(Clock,AD,LC,S0,S1);

        if (Direction != AD);

          Population(ij,3) = Population(ij,3) + LC + IIF(AD == 0,S0,S1) - Clock;

        endif;

      end;

  end;

  History(ijk) = mean(Population[:,3]');

  Signal = printf("Generation %3.0f  ",ijk) | printf("Mean Wait time %7.3f",History[ijk])

  ## replace items with wait time higher of mean

  loop 1 to 100;

    if Population(#,3) > History(ijk);

      if random(1,1)*100 < Speed; Population(#,2) = SemTime*random(1,1); endif;

    endif;

  end;

end;

S0 = ceil(mean(Population[:,2]'));

Signal = printf("Proposed seconds for S0: %3.0f ",S0)|printf(", for S1: %3.0f",SemTime - S0)

return History';

endfunction

linewidth(2);

setplot(0,51,3500,4600);

color(10);        ## line color red

plot(1:50,Main(50,10));

hold on;          ## mantains draws

color(3);

plot(1:50,Main(50,20));

xplot();          ## plot grids

title("50 Generation with 10% and 20% replacements");

postscript "Semaphor.ps";

 

...

Generation  37  Mean Wait time 3822.761

Generation  38  Mean Wait time 3893.483

Generation  39  Mean Wait time 3846.253

Generation  40  Mean Wait time 3757.252

Generation  41  Mean Wait time 3699.345

Generation  42  Mean Wait time 3699.388

Generation  43  Mean Wait time 3701.330

Generation  44  Mean Wait time 3706.968

Generation  45  Mean Wait time 3701.906

Generation  46  Mean Wait time 3730.799

Generation  47  Mean Wait time 3726.342

Generation  48  Mean Wait time 3732.744

Generation  49  Mean Wait time 3722.844

Generation  50  Mean Wait time 3682.776

Proposed seconds for S0:  50 , for S1:  40




4             Euler graph rewriting

Euler è un lcc (linear concurrent constraints)  languaggio per manipolare grafi (Vijay Saraswat, IBM TJ Watson Research Center  2004).