;;;;;;;;;;;;;;;;;;;;;;;;
If your browser supports JAVA, you can display the data in a graph by checking the Graphic output box on the interface page.;;; ;;; This file contains the ACT-R model of the ;;; Glenberg free recall experiment ;;; presented in Chapter 5 ;;; ;;; ACT-R version 4 required ;;; ;;; A WWW interface and a command line interface ;;; are provided. ;;; To run the command line version, call ;;; (do-glenberg n) ;;; replacing n with the number of runs to ;;; simulate. ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; This section contains the LISP functions to simulate ;;; the experiment, implement the interface, collect the ;;; data, and display the results ;;; ;;; The ACT-R Model starts further down ;;; ;;; Global variables (defvar *history*) (defvar *items*) (defvar *data*) (defvar *index*) (defvar *counter*) (defvar *predictions*) (defvar *thresh*) (defvar *noise*) (defvar *respond*) (defvar *factor*) (defvar *runs*) (defvar *v*) (defvar *text*) (defvar *graphic*) (defvar *overlay*) (setf *thresh* 1.4) (setf *noise* .6) (setf *respond* 0.5) (setf *factor* 2) (setf *runs* 1) (setf *v* nil) (setf *text* t) (setf *graphic* nil) (setf *overlay* nil) (defparameter *glenberg-contexts* '(l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 l11 l12 l13 l14 l15 l16 l17 l18 l19 l20)) (defparameter *glenberg-results* (make-array '(2 36) :initial-contents '(( 0.18 0.17 0.19 0.19 0.24 0.18 0.15 0.41 0.68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0.10 0.08 0.08 0.05 0.07 0.05 0.07 0.10 0.10 0.06 0.10 0.11 0.06 0.06 0.06 0.10 0.02 0.07 0.05 0.09 0.09 0.09 0.06 0.08 0.07 0.07 0.14 0.11 0.10 0.10 0.13 0.19 0.21 0.18 0.20 0.33)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; This section contains the interface for the WWW using the ;;; ACT-R on the Web application by Elmar Schwarz (defvar *WWW-interface*) (setf *WWW-interface* '((:heading "Glenberg Experiment model" 2) (:table) (:table) "Noise (s): " (:string :sy *noise* .6) (:new-row) "Threshold: " (:string :sy *thresh* 1.4) (:new-row) "Factor (F):" (:string :sy *factor* 2) (:new-row) "Response time (sec.): " (:string :sy *respond* .5) (:new-row) "Number of runs (1-20): " (:string :sy *runs* 1) (:table-end) (:table) (:checkbox "Trace" :sy *v* nil) (:new-row) (:checkbox "Text output" :sy *text* t) (:new-row) (:checkbox "Graphic output" :sy *graphic* nil) (:new-row) (:checkbox "Show simulation and experiment data on one graph" :sy *overlay* nil) (:table-end) (:table-end) (:new-para) (:button "Show Experiment Results" "(display-glenberg-data *glenberg-results* 1 nil)") (:new-para) (:button "Run model" "(if (and (numberp *thresh*) (numberp *noise*) (numberp *factor*) (numberp *runs*) (numberp *respond*)) (do-glenberg (min 20 (max 1 *runs*))) (format *standard-output* \"All parameters must be numbers~%\"))") (:reset "Default values") (:button "Production Rules" "(let ((prods (no-output (pp)))) (dolist (x prods) (pp-fct (list x)) (spp-fct (list x)) (format *standard-output* \"~%\")))") (:button "Chunk types" "(chunk-type)") (:button "Chunks" "(dm)") (:new-para) "TIME and SIZE:" (:new-para) "- It usually takes less than 1 minute for 1 run of the model" (:new-line) "- The trace of 1 run is approximatly 2k (2 pages) in size" (:new-para))) ;;; reset-wme-number-glenberg takes one parameter ;;; which is ignored, and sets the number of ;;; chunks to be 100 ;;; this function is hooked to the actr ;;; cycle-hook-fn, so that the number ;;; of chunks is always 100 ;;; to prevent problems with ia's ;;; changing for the different size lists (defun reset-wme-number-glenberg (instantiation) (declare (ignore instantiation)) (setf *wme-number* 100)) ;;; set-glenberg-params is used to set ;;; the parameters of the model before each run ;;; it is needed for the WWW interface (defun set-glenberg-params () (setf *cycle-hook-fn* #'reset-wme-number-glenberg) (sgp-fct (list :bll 0.5 :ans *noise* :rt *thresh* :er t :lf *factor* :v *v* :al nil)) (parameters-fct 'recall-a-word (list :effort *respond*))) ;;; display-glenberg-data takes 3 parameters ;;; an array containg data for a simulation ;;; of the glenberg experiment, the ;;; number of runs that the array contains ;;; data for, and whether the data is for the ;;; simulation, or experimental data. ;;; it displays the data in either text, a graph (on the web), ;;; or both, depending on the settings of *text* and *graphic* (defun display-glenberg-data (data count simulation) (when simulation (format *standard-output* "~%~%Parameters for run: (~S ~S ~S ~S ~S)~%" *noise* *thresh* *factor* *respond* count)) (when *text* (format *standard-output* "~%~A data:~%" (if simulation "Simulation" "Experimental")) (format *standard-output* "~%Percentage recalled:~%") (format *standard-output* "9 pairs:~%") (dotimes (x 9) (format *standard-output* "~3D% " (round (* 100 (/ (aref data 0 x) count))))) (format *standard-output* "~%36 pairs:~%") (dotimes (x 36) (format *standard-output* "~3D% " (round (* 100 (/ (aref data 1 x) count))))) (format *standard-output* "~%") (when (and simulation *overlay*) (format *standard-output* "~%Experimental data:~%") (format *standard-output* "~%Percentage recalled:~%") (format *standard-output* "9 pairs:~%") (dotimes (x 9) (format *standard-output* "~3D% " (round (* 100 (aref *glenberg-results* 0 x))))) (format *standard-output* "~%36 pairs:~%") (dotimes (x 36) (format *standard-output* "~3D% " (round (* 100 (aref *glenberg-results* 1 x))))) (format *standard-output* "~%")) (unless *graphic* (format *standard-output* "~%
~%~%")))
(when *graphic*
(format *standard-output* "
")))
;;; setup-glenberg takes 2 parameters
;;; a name for a word chunk, and
;;; the number of previous contexts that word occured
;;; in, and returns the list of chunk definitions
;;; for the previous contexts
(defun setup-glenberg (word n)
(add-dm-fct (list (list word 'isa 'word)))
(do ((count 0 (1+ count))
(result nil (cons `(,(gentemp "C") isa memory-token
context ,(nth count *glenberg-contexts*)
name ,word) result)))
((= count n) result)))
;;; setup-glenberg-materials takes one parameter
;;; the number of words to create, and
;;; generates the word chunks, and the
;;; previous context chunks for the words,
;;; and the sets the base levels for the items,
;;; and returns the list of word chunk
;;; names
(defun setup-glenberg-materials (n)
(do ((count 0 (1+ count))
(items nil (append (setup-glenberg (gentemp "I") 1) items)))
((= count n)
(eval `(addwm ,@items))
(setallbaselevels 10 -400)
(remove-duplicates (mapcar 'seventh items)))))
;;; do-glenberg takes one parameter
;;; the number of runs to simulate,
;;; and runs the experiment
;;; that many times, displaying a table
;;; of the results when finished
(defun do-glenberg (n)
(let ((final (make-array '(2 36) :initial-element 0)))
(do ((count 0 (1+ count)))
((equal count n) (setf *predictions* final))
(let ((temp (glenberg-conditions)))
(do ((j 0 (1+ j)))
((equal j 2) nil)
(do ((k 0 (1+ k)))
((equal k 36) nil)
(setf (aref final j k) (+ (aref final j k) (/ (aref temp j k) 2.0)))))))
(display-glenberg-data *predictions* n t)))
;;; glenberg-conditions takes no parameters
;;; and runs one simulation of each condition
;;; of the glenberg experiment in a random order
;;; and returns the data array of the results
(defun glenberg-conditions ()
(setf *data* (make-array '(2 36) :initial-element 0))
(let ((ordered (list '(run-glenberg-experiment 9 24 0)
'(run-glenberg-experiment 36 6 1) )))
(dotimes (i 2)
(let ((exp-run (nth (random (- 2 i)) ordered)))
(setf ordered (delete exp-run ordered))
(reset)
(set-glenberg-params)
(eval exp-run)))
*data*))
;;; run-glenberg-experiment takes 3 parameters,
;;; the number of word pairs for the run, the amount
;;; of time for study (in seconds), and the index
;;; of this condition in the data array *data*
;;; it then creates the memory tokens to simulate
;;; the studying of the items and runs the simulation
;;; of the recall
(defun run-glenberg-experiment (n time index)
(setf *index* index)
(setf *wme-number* 100)
(let* ((materials (setup-glenberg-materials (* n 2))))
(setallbaselevels 500 -1000)
(reset-wme-number-glenberg nil)
(reset-ia)
(setf *items* (no-output (wm-fct materials)))
(setf *history* *items*)
(do ((items materials (cddr items)))
((null items) nil)
(actr-time-fct time)
(eval `(addwm (,(gentemp "C") isa memory-token
context L0
name ,(car items))
(,(gentemp "C") isa memory-token
context L0
name ,(cadr items)))))
(actr-time 20)
(addwm (goal isa recall-words context L0))
(wmfocus goal)
(setf *counter* 1)
(run)))
;;; analyze-glenberg takes one parameter
;;; a word chunk, and updates the results
;;; array for the position of the word in
;;; the study list
(defun analyze-glenberg (word)
(setf (aref *data* *index* (floor (/ (position word *history*) 2)))
(1+ (aref *data* *index* (floor (/ (position word *history*) 2)))))
(setf *counter* (1+ *counter*)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; ACT-R Model of the task
;;;
;;;
(clearall)
(sgp-fct (list :bll 0.5 :ans *noise* :rt *thresh* :er t :lf *factor* :v nil :al nil))
(chunk-type study-words first position context)
(chunk-type memory-token name status context)
(chunk-type context)
(chunk-type rehearse target)
(chunk-type output target)
(chunk-type recall-words context)
(chunk-type type-word position word)
(chunk-type dump-words first position context)
(chunk-type word)
; adds the contexts to working memory
(add-dm (l0 isa context)
(l1 isa context))
(setallbaselevels 500 -1000)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Productions
;;;
(p recall-a-word
"
IF the goal is to recall words
and a memory token with the
current context that has not
been previously recalled can be
recalled
THEN mark the memory token as having been recalled
and respond with the word
"
=goal>
isa recall-words
context =context
=token>
isa memory-token
status nil
name =name
context =context
==>
=token>
status recalled
!eval! (analyze-glenberg =name)
)
(parameters-fct 'recall-a-word (list :effort *respond*))
(p stop-recall
"
IF the goal is to recall words
THEN pop the goal
"
=goal>
isa recall-words
==>
!pop!
)
(parameters stop-recall :r .25)