(in-package :maxima) ;; uh, for now (eval-when (:compile-toplevel :load-toplevel) (proclaim (optimize (speed 3)(safety 1)(space 0) ))) ;;;; -*- Mode: Lisp; Syntax: Common-Lisp -*- ;;;; Code from Paradigms of AI Programming ;;;; Copyright (c) 1991 Peter Norvig ;;; ============================== ;;;; The Memoization facility: (defmacro defun-memo (fn args &body body) "Define a memoized function." `(memoize (defun ,fn ,args . ,body))) (defun memo (fn &key (key #'first) (test #'eql) name) "Return a memo-function of fn." (let ((table (make-hash-table :test test))) (setf (get name 'memo) table) #'(lambda (&rest args) (let ((k (funcall key args))) (multiple-value-bind (val found-p) (gethash k table) (if found-p val (setf (gethash k table) (apply fn args)))))))) (defun memoize (fn-name &key (key #'first) (test #'eql)) "Replace fn-name's global definition with a memoized version." (clear-memoize fn-name) (setf (symbol-function fn-name) (memo (symbol-function fn-name) :name fn-name :key key :test test)) (compile fn-name);; added; compile always? ) (defun clear-memoize (fn-name) "Clear the hash table from a memo function." (let ((table (get fn-name 'memo))) (when table (clrhash table)))) ;; end of norvig code ;; debugging pgm to print out memo table (defun dmpmemoht (h)(maphash #'(lambda (k v)(format t "~%key= ~s value=~s" k v)) (get h 'memo))) ;;; now to hack Maxima.. ;; maybe (memoize 'great :key #'sxhash) ;; sxhash will be called on (a b) for (great a b) ;; maybe (memoize 'great :key #'identity) ;; maybe slower but at least 100% the same. ;; first, save original simplifya definition unless it has already been saved. (unless (fboundp 'simplifya_orig) (setf (symbol-function 'simplifya_orig) (symbol-function 'simplifya))) ;; now memoize the separate kinds of simplify (defun-memo simplifya_t (a)(simplifya_orig a t)) (defun-memo simplifya_nil (a)(simplifya_orig a nil)) (defun simplifya(a b)(if b (simplifya_t a)(simplifya_nil a))) ;;run_testsuite(tests=[rtest1,rtest2,rtest_rules]); ;; regular time is 4.812 sec run time ;; after loading this, 5.031 sec run time ;; BUT if the test is run a second time, the ;; test takes 2.82 seconds ;; and uses half the bytes consed. ;; some of the other tests give answers that are simplified differently though. ;; To make this work "the same" we could require that any ;; change to the global environment that affects the ;; result of (simplifya ..) should also clear the memo table ;; for simplifya. ;; As an obvious example, tellsimp(...) must also do (clear-memoize 'simplifya). ;; That's not all though. ;; Changes to variable settings like expon, expop,radexpand,negdistrib, ;; expandwrt_denom, exponentialize must also call clear-memoize. ;; Also changes or declarations of properties including ;; linear, additive, multiplicative, outative, evenfun, oddfun, ;; commutative, symmetric, antisymmetric, nary, lassociative, rassociative. ;; Maybe other things too. ;;RJF 9/5/2016