/*
   Sat Nov 29 19:56:48 2008/hakank@bonetmail.com   


   Memo function, from 
   The Pop book by Robin Popplestone, page 287ff
   http://www.cs.bham.ac.uk/research/projects/poplog/popbook/popbook.html

   Usage:

   define fact(n);
      if n=0 then 
         1 
      else 
         n*fact(n-1)
     endif;
   enddefine;
    
   newmemo(fact,20) -> fact;
   fact(100)=>
   ** 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
: 

*/


define auxmemo(O1, Prop, P,n, ref_i)->O2;

    lvars O1,O2, Prop, P, n,i, ref_i;
    ref_i.cont-1 ->> i -> ref_i.cont;
    if i = 0 then n -> ref_i.cont;
        clearproperty(Prop);
    endif;

    P(O1) -> O2;
    O2 -> Prop(O1);

enddefine;

;;;
;;; P: Procedure
;;; n: number of values to keep, then the cache is cleared and
;;;    memoizing restarts.
;;;
define newmemo(P,n);
  newanyproperty([], n, false, false, syshash, nonop=, false, undef,
                 auxmemo(%P,n,consref(n)%));
enddefine;


