+/****************************************************************************
+Ejercicio: 1.9b
+Alumno: Leandro Lucarella
+Fecha: lun abr 4 01:16:56 ART 2005
+****************************************************************************/
+
+functor
+import
+ Application
+ System
+define
+% Obtenido de internet porque no me funcionaba el {NewStore}
+% (http://www.info.ucl.ac.be/people/PVR/ds/booksuppl.oz)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The memory store as used in the exercises
+fun {NewStore}
+ D={NewDictionary}
+ C={NewCell 0}
+ proc {Put K X}
+ if {Not {Dictionary.member D K}} then
+ C:=@C+1
+ end
+ D.K:=X
+ end
+ fun {Get K} D.K end
+ fun {Size} @C end
+in
+ storeobject(put:Put get:Get size:Size)
+end
+proc {Put S K X} {S.put K X} end
+fun {Get S K} {S.get K} end
+fun {Size S} {S.size} end
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % Concatena un 0 al final de la lista
+ fun {ShiftLeft L}
+ case L of H|T then
+ H|{ShiftLeft T}
+ else [0] end
+ end
+ % Inserta un 0 al inicio de la lista
+ fun {ShiftRight L} 0|L end
+ % Aplica una operación entre 2 elementos de dos listas
+ fun {OpList Op L1 L2}
+ case L1 of H1|T1 then
+ case L2 of H2|T2 then
+ {Op H1 H2}|{OpList Op T1 T2}
+ end
+ else nil end
+ end
+ % Calcula variaciones del Triánculo de Pascal
+ fun {GenericPascal Op N}
+ if N == 1 then [1]
+ else L in
+ L = {GenericPascal Op N-1}
+ {OpList Op {ShiftLeft L} {ShiftRight L}}
+ end
+ end
+ % Suma
+ fun {Sum X Y} X+Y end
+ % Celda para almacenar cantidad de veces que se llama al FastPascal
+ S = {NewStore}
+ % Funcion con "memoria"
+ fun {FasterPascal N}
+ if N > {Size S} then
+ if N > 1 then % Si tenemos que calcular anteriores
+ % Tengo que hacer un local porque si no lo asigno como una
+ % variable al resultado de la función, lo toma como el retorno
+ % de la actual y da error de aridad.
+ local DUMMY in DUMMY = {FasterPascal N-1} end
+ end
+ {Put S N {GenericPascal Sum N}}
+ end
+ {Get S N}
+ end
+ {System.show {FasterPascal 10}}
+ {Application.exit 0}
+end
+
+% vim: set et sw=4 sts=4 filetype=oz :