/**
 * The memo operator makes a strategy
 * into a memoizing strategy that looks up the term to be transformed
 * in a memo table and only computes the transformation if the
 * term is not found.
 */
module strategy/general/memo
imports
  lang/dynamic-rules

strategies

  memo-scope(s) = {| Memo: s |}

 /**
  * <memo(tbl, s)> t first looks up the term t in the memo table. If 
  * present the association in the table is produced, else the result 
  * of <s> t is computed and stored in the table.
  */
  memo(s) :
    t -> t'
    where ( <Memo> t => t' )
       <+ ( <s> t => t'; rules(Memo: t -> t') )