;;;;;;;;;;;;;;;;;;;;;;;;
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 ;;; length-strength effect presented in Chapter 7 ;;; ;;; A WWW interface and a command line interface ;;; are provided. ;;; To run the command line version, call ;;; (do-len-str n) ;;; replacing n with the number of runs to ;;; simulate. ;;; ;;; requires ACT-R 4.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; 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 *stop-it*) (defvar *items*) (defvar *h*) (defvar *f*) (defvar *t*) (defvar *t1*) (defvar *t4*) (defvar *data*) (defvar *index*) (defvar *thresh*) (defvar *penalty*) (defvar *noise*) (defvar *d-sim*) (defvar *v*) (defvar *runs*) (defvar *factor*) (defvar *rehearsals*) (defvar *respond*) (defvar *encode*) (defvar *rehearse*) (defvar *text*) (defvar *graphic*) (defvar *overlay*) (setf *respond* .5) (setf *encode* .2) (setf *rehearse* .5) (setf *thresh* 1.8) (setf *penalty* 15) (setf *noise* .55) (setf *factor* 2) (setf *v* nil) (setf *text* t) (setf *graphic* nil) (setf *overlay* nil) (defparameter *len-str-contexts* '(l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 l11 l12 l13 l14 l15 l16 l17 l18 l19 l20)) (defparameter *len-str-cumul* '(-2.58 -2.17 -1.96 -1.81 -1.70 -1.60 -1.51 -1.44 -1.37 -1.31 -1.25 -1.20 -1.15 -1.10 -1.06 -1.02 -0.97 -0.93 -0.90 -0.86 -0.82 -0.79 -0.76 -0.72 -0.69 -0.66 -0.63 -0.60 -0.57 -0.54 -0.51 -0.48 -0.45 -0.43 -0.40 -0.37 -0.34 -0.32 -0.29 -0.27 -0.24 -0.21 -0.19 -0.16 -0.14 -0.11 -0.09 -0.06 -0.04 -0.01 0)) (defparameter *len-str-d-data* '(2.62 2.32 2.38 1.49 1.48 1.09)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; 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 "Ratcliff Experiment model" 2) (:table) (:table) "Noise (s):" (:string :sy *noise* .55) (:new-row) "Threshold:" (:string :sy *thresh* 1.8) (:new-row) "Latency scale (F):" (:string :sy *factor* 2) (:new-row) "Penalty:" (:string :sy *penalty* 1.5) (:new-row) "Response time (sec.): " (:string :sy *respond* .5) (:new-row) "Encoding time (sec.): " (:string :sy *encode* .2) (:new-row) "Rehearsal time (sec.): " (:string :sy *rehearse* .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-len-str *len-str-d-data* nil)") (:new-para) (:button "Run model" "(progn (when (numberp *penalty*) (setf *penalty* (* 10 *penalty*))) (if (and (numberp *penalty*) (numberp *thresh*) (numberp *noise*) (numberp *factor*) (numberp *runs*) (numberp *encode*) (numberp *rehearse*) (numberp *respond*)) (do-len-str (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 150k (100 pages) in size" (:new-para))) ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; This section contains the LISP functions to simulate ;;; the experiment, and display the results ;;; set-len-str-parameters is used to set ;;; the parameters of the model before each run ;;; it is needed for the WWW interface (defun set-len-str-params () (sgp-fct (list :bll .5 :ans *noise* :mp *penalty* :ol t :pm t :rt *thresh* :lf 2 :v *v*)) (parameters-fct 'attend (list :effort *encode*)) (parameters-fct 'rehearse-token-1 (list :effort *rehearse*)) (parameters-fct 'rehearse-token-2 (list :effort *rehearse* :r .9)) (parameters-fct 'rehearse-token-3 (list :effort *rehearse* :r .8)) (parameters-fct 'rehearse-skip (list :r .5 :effort *rehearse*)) (parameters-fct 'attend-test (list :a *encode*)) (parameters-fct 'accept-word (list :effort *respond*)) (parameters-fct 'reject-a-word-2 (list :r .5 :effort *respond*)) (setf *rehearsals* nil)) ;;; len-str-innorm takes one parameter, ;;; a probability, and returns the value ;;; from the *len-str-cumul* with the correct ;;; sign for calculation of the d' value (defun len-str-innorm (p) (let ((index (round (* p 100)))) (cond ((> index 50) (* -1 (nth (- 100 index) *len-str-cumul*))) ((< index 50) (nth index *len-str-cumul*)) (t 0)))) ;;; len-str-setup takes 2 parameters, ;;; a word to add to memory, ;;; and the number of memory-tokens that ;;; should be created for the word. ;;; each memory-token is created with a ;;; different context (defun len-str-setup (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 *len-str-contexts*) name ,word) result))) ((= count n) result))) ;;; display-len-str takes two parameters ;;; the results data to display and a flag to specify if the ;;; data is for a simulation ;;; and outputs a display of the d' ;;; values for the data, in either text, a graph (on the web), ;;; or both, depending on the settings of *text* and *graphic* (defun display-len-str (data simulation) (when simulation (format *standard-output* "~%~%Parameters for run: (~S ~S ~S ~S ~S ~S ~S ~S)~%" *noise* *thresh* *factor* (/ *penalty* 10.0) *respond* *encode* *rehearse* *runs*)) (when *text* (format *standard-output* "~%~%~a d' values:~%" (if simulation "Simulation" "Experimental")) (format t "10PS 16PS 16MS 16MW 16PW 40PW~%") (dolist (x data) (format *standard-output* "~4,2F " x)) (format *standard-output* "~%") (when (and simulation *overlay*) (format *standard-output* "~%Experimental d' values:~%") (format t "10PS 16PS 16MS 16MW 16PW 40PW~%") (dolist (x *len-str-d-data*) (format *standard-output* "~4,2F " x)) (format *standard-output* "~%")) (unless *graphic* (format *standard-output* "~%
~%~%")))
(when *graphic*
(format *standard-output* "
")))
;;; do-len-str takes one parameter n,
;;; the number of runs through the experiment
;;; to simulate, and then performs that many simulations
;;; setting the global variable *d-sim* to the
;;; d' results and displays the d' results
(defun do-len-str (n)
(setf *data* (make-array '(6 2 2) :initial-element 0))
(do ((count 0 (1+ count)))
((= count n)
(do ((i 0 (1+ i))
(result nil (cons (len-str-d-prime *data* i) result)))
((= i 6) (setf *d-sim* (reverse result))
(display-len-str *d-sim* t))))
(reset) (set-len-str-params)(run-len-str-exp-10-4)
(reset) (set-len-str-params)(run-len-str-exp-16-4)
(reset) (set-len-str-params)(run-len-str-exp-16-mixed)
(reset) (set-len-str-params)(run-len-str-exp-16-mixed)
(reset) (set-len-str-params)(run-len-str-exp-16-mixed)
(reset) (set-len-str-params)(run-len-str-exp-16-1)
(reset) (set-len-str-params)(run-len-str-exp-40-1)))
;;; len-str-d-prime takes two parameters,
;;; an array of data and the first index into the
;;; array, and returns the d-prime value for the
;;; condition at the index in the array
(defun len-str-d-prime (array index)
(let* ((pt (/ (aref array index 0 0) (+ (aref array index 0 0)
(aref array index 0 1))))
(pf (/ (aref array index 1 0) (+ (aref array index 1 0)
(aref array index 1 1)))))
(- (len-str-innorm pt) (len-str-innorm pf))))
;;; len-str-setup-materials takes one
;;; parameter, the number of words to add
;;; to the memory. The words are generated
;;; and added to memory with the appropriate
;;; memory tokens.
(defun len-str-setup-materials (n)
(do ((count 0 (1+ count))
(items nil (append (len-str-setup (gentemp "I") 3) items)))
((= count n)
(eval `(addwm ,@items))
(setallbaselevels 10 -400)
(remove-duplicates (mapcar 'seventh items)))))
;;; run-len-str-exp-16-1
;;; sets up the memory items and
;;; runs the 16PW condition of the experiment
(defun run-len-str-exp-16-1 ()
(setf *index* 4)
(let* ((materials (len-str-setup-materials 32))
(study (nthcdr 16 materials))
(test (nthcdr 16 (reverse materials))))
(setsimilarities (l0 l1 .9)(l0 l2 .9)(l0 l3 .9)
(l1 l2 .9)(l1 l3 .9))
(setf *stop-it* 0)
(setf *t* (no-output (wm-fct study)))
(setf *f* (no-output (wm-fct test)))
(addwm (goal isa study-words context L0))
(setf *items* *t*)
(wmfocus goal) (sgp :pm nil)
(run)
(setf *items* (len-str-permut (append *t* *f*))) (actr-time 30)
(addwm (newgoal isa recognize-words context L0))
(do ((temp *t* (cdr temp)))
((null temp) nil)
(no-output (setia-fct (list (list 'l0 (car (sdm-fct (list 'isa 'memory-token
'name (car temp) 'context 'l0)))
(- 4.5 (log 16)))))))
(wmfocus newgoal) (sgp :pm t)
(run)))
;;; run-len-str-exp-16-mixed
;;; sets up the memory items and
;;; runs the 16MS and 16MW conditions of the experiment
(defun run-len-str-exp-16-mixed ()
(setf *index* 2)
(let* ((materials (len-str-setup-materials 32))
(study (nthcdr 16 materials))
(ones (nthcdr 8 study))
(fours (nthcdr 8 (reverse study)))
(test (nthcdr 16 (reverse materials))))
(setsimilarities (l0 l1 .9)(l0 l2 .9)(l0 l3 .9)
(l1 l2 .9)(l1 l3 .9))
(setf *stop-it* 0)
(setf *t1* (no-output (wm-fct ones)))
(setf *t4* (no-output (wm-fct fours)))
(setf *t* (append *t1* *t4*))
(setf *f* (no-output (wm-fct test)))
(addwm (goal isa study-words context L0))
(setf *items* (len-str-permut (append *t1* *t4* *t4* *t4* *t4*)))
(wmfocus goal) (sgp :pm nil)
(run)
(setf *items* (len-str-permut (append *t1* *t4* *f*))) (actr-time 30)
(addwm (newgoal isa recognize-words context L0))
(do ((temp *t* (cdr temp)))
((null temp) nil)
(no-output (setia-fct (list (list 'l0 (car (sdm-fct (list 'isa 'memory-token
'name (car temp) 'context 'l0)))
(- 4.5 (log 16)))))))
(wmfocus newgoal) (sgp :pm t)
(run)))
;;; run-len-str-exp-40-1
;;; sets up the memory items and
;;; runs the 40PW condition of the experiment
(defun run-len-str-exp-40-1 ()
(setf *index* 5)
(let* ((materials (len-str-setup-materials 60))
(study (nthcdr 20 materials))
(test (nthcdr 20 (reverse materials))))
(setsimilarities (l0 l1 .9)(l0 l2 .9)(l0 l3 .9)
(l1 l2 .9)(l1 l3 .9))
(setf *stop-it* 0)
(setf *f* (no-output (wm-fct (nthcdr 20 test))))
(setf *t* (no-output (wm-fct (nthcdr 20 (reverse test)))))
(addwm (goal isa study-words context L0))
(setf *items* (len-str-permut (no-output (wm-fct study))))
(wmfocus goal) (sgp :pm nil)
(run)
(setf *items* (len-str-permut (append *t* *f*))) (actr-time 30)
(addwm (newgoal isa recognize-words context L0))
(do ((temp *t* (cdr temp)))
((null temp) nil)
(no-output (setia-fct (list (list 'l0 (car (sdm-fct (list 'isa 'memory-token
'name (car temp) 'context 'l0)))
(- 4.5 (log 40)))))))
(wmfocus newgoal)(sgp :pm t)
(run)))
;;; run-len-str-exp-16-4
;;; sets up the memory items and
;;; runs the 16PS condition of the experiment
(defun run-len-str-exp-16-4 ()
(setf *index* 1)
(let* ((materials (len-str-setup-materials 32))
(study (nthcdr 16 materials))
(test (nthcdr 16 (reverse materials))))
(setsimilarities (l0 l1 .9)(l0 l2 .9)(l0 l3 .9)
(l1 l2 .9)(l1 l3 .9))
(setf *stop-it* 0)
(setf *t* (no-output (wm-fct study)))
(setf *f* (no-output (wm-fct test)))
(addwm (goal isa study-words context L0))
(setf *items* (append (len-str-permut *t*) (len-str-permut *t*) (len-str-permut *t*) (len-str-permut *t*)))
(wmfocus goal) (sgp :pm nil)
(run)
(setf *items* (len-str-permut (append *t* *f*))) (actr-time 30)
(addwm (newgoal isa recognize-words context L0))
(do ((temp *t* (cdr temp)))
((null temp) nil)
(no-output (setia-fct (list (list 'l0 (car (sdm-fct (list 'isa 'memory-token
'name (car temp) 'context 'l0)))
(- 4.5 (log 16)))))))
(wmfocus newgoal) (sgp :pm t)
(run)))
;;; run-len-str-exp-10-4
;;; sets up the memory items and
;;; runs the 10PS condition of the experiment
(defun run-len-str-exp-10-4 ()
(setf *index* 0)
(let* ((materials (len-str-setup-materials 20))
(study (nthcdr 10 materials))
(test (nthcdr 10 (reverse materials))))
(setsimilarities (l0 l1 .9)(l0 l2 .9)(l0 l3 .9)
(l1 l2 .9)(l1 l3 .9))
(setf *stop-it* 0)
(setf *t* (no-output (wm-fct study)))
(setf *f* (no-output (wm-fct test)))
(addwm (goal isa study-words context L0))
(setf *items* (append (len-str-permut *t*) (len-str-permut *t*) (len-str-permut *t*) (len-str-permut *t*)))
(wmfocus goal) (sgp :pm nil)
(run )
(setf *items* (len-str-permut (append *t* *f*))) (actr-time 30)
(addwm (newgoal isa recognize-words context L0))
(do ((temp *t* (cdr temp)))
((null temp) nil)
(no-output (setia-fct (list (list 'l0 (car (sdm-fct (list 'isa 'memory-token
'name (car temp) 'context 'l0)))
(- 4.5 (log 10)))))))
(wmfocus newgoal)(sgp :pm t)
(run)))
(defun prob-len-str (word s tau)
(let ((xx (no-output (eval `(swm isa memory-token name ,word)))))
(do ((temp xx (cdr temp))
(result 0 (+ result (exp (/ (c-activation-len-str (car temp) (/ *penalty* 10))
s)))))
((null temp) (/ result (+ result (exp (/ tau s))))))))
(defun c-activation-len-str (token d)
(let ((act (apply '+ (car (no-output (eval `(sdp ,token :base-level :source-spread)))))))
(cond ((equal (no-output (car (dm l0))) (eval `(chunk-slot-value ,token context)))
act)
(t (- act d)))))
;;; len-str-analyze takes two parameters,
;;; a test word, and a response, and
;;; updates the results for the experiment
;;; based on the models response to the word
(defun len-str-analyze (word response)
(let* ((i)
(prob (prob-len-str word *noise* *thresh*))
(q (- 1.0 prob)))
(cond ((= *index* 2)
(cond ((member word *t4*)
(setf (aref *data* 2 0 0)
(+ prob (aref *data* 2 0 0)))
(setf (aref *data* 2 0 1)
(+ q (aref *data* 2 0 1))))
((member word *t1*)
(setf (aref *data* 3 0 0)
(+ prob (aref *data* 3 0 0)))
(setf (aref *data* 3 0 1)
(+ q (aref *data* 3 0 1))))
((member word *f*)
(setf (aref *data* 2 1 0)
(+ prob (aref *data* 2 1 0)))
(setf (aref *data* 2 1 1)
(+ q (aref *data* 2 1 1)))
(setf (aref *data* 3 1 0)
(+ prob (aref *data* 3 1 0)))
(setf (aref *data* 3 1 1)
(+ q (aref *data* 3 1 1))))))
(t (cond
((member word *t*)(setf i 0))
((member word *f*)(setf i 1)))
(setf (aref *data* *index* i 0)
(+ prob (aref *data* *index* i 0)))
(setf (aref *data* *index* i 1)
(+ q (aref *data* *index* i 1)))))))
;;; len-str-get-word
;;; increments the time until the next word is to
;;; be presented, and returns the current word to study
(defun len-str-get-word ()
(setf *stop-it* (+ 1.25 *stop-it*))
(pop *items*))
;;; len-str-permut takes one parameter,
;;; a list, and returns the list in random order
(defun len-str-permut (lis)
(do ((result (list (nth (random (length lis)) lis))
(cons (nth (random (length lis)) lis) result)))
((null lis) result)
(setf lis (remove (car result) lis :count 1))
(cond ((null lis) (return result)))))
;;; update-rehearsals-len-str takes one parameter
;;; and increments the count of how many times that
;;; word has been rehearsed
(defun update-rehearsals-len-str (x)
(let ((result (assoc x *rehearsals* :test 'equal)))
(cond ((null result) (setf *rehearsals* (cons (cons x 1) *rehearsals*)))
(t (rplacd result (1+ (cdr result)))))))
;;; rehearsal-count-len-str takes one parameter,
;;; a word from the study, and returns how many times
;;; that word has been rehearsed
(defun rehearsal-count-len-str (x)
(let ((result (assoc x *rehearsals* :test 'equal)))
(cond ((null result) 0)
(t (cdr result)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; This section contains the ACT-R model
;;;
;;;
(clearall)
(sgp-fct (list :bll .5 :ans *noise* :mp *penalty* :ol t
:pm t :rt *thresh* :lf 2 :v *v*))
(setf *rehearsals* nil)
;;; memory types for the model
(wmetype study-words count context)
(wmetype recognize-words context target)
(wmetype memory-token name context)
(wmetype context)
(wmetype word)
;;; add the contexts to memory
(add-dm (l0 isa context)
(l1 isa context)
(l2 isa context)
(l3 isa context))
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; productions
(p attend
"
IF the goal is to study words
and there are items to study
and it is not past time for this word
THEN create a new memory-token with the
current context and push it as a goal
"
=goal>
isa study-words
context =context
!eval! (>= (actr-time) *stop-it*)
!eval! *items*
==>
=newgoal>
isa memory-token
context =context
=goal>
count =newgoal
!push! =newgoal
)
(parameters-fct 'attend (list :effort *encode*))
(p create-token
"
IF the goal is to create a memory token
THEN get the current word
and store it in the memory token
and pop the goal
"
=goal>
isa memory-token
context =context
==>
=goal>
name (!eval! (len-str-get-word))
!pop!
)
(p rehearse-token-1
"
IF the goal is to study words
and there is still time to study this word
and there is a memory token with the
current context that has not been
rehearsed yet
THEN update the number of rehearsals for that word
"
=goal>
isa study-words
count =n
context =context
!eval! (< (actr-time) *stop-it*)
=memory>
isa memory-token
name =name
name (!eval! (if (< (rehearsal-count-len-str =name) 1) =name))
context =context
==>
!eval! (update-rehearsals-len-str =name)
)
(parameters-fct 'rehearse-token-1 (list :effort *rehearse*))
(p rehearse-token-2
"
IF the goal is to study words
and there is still time to study this word
and there is a memory token with the
current context that has been
rehearsed at most 1 time
THEN update the number of rehearsals for that word
"
=goal>
isa study-words
count =n
context =context
!eval! (< (actr-time) *stop-it*)
=memory>
isa memory-token
name =name
name (!eval! (if (< (rehearsal-count-len-str =name) 2) =name))
context =context
==>
!eval! (update-rehearsals-len-str =name)
)
(parameters-fct 'rehearse-token-2 (list :effort *rehearse* :r .9))
(p rehearse-token-3
"
IF the goal is to study words
and there is still time to study this word
and there is a memory token with the
current context that has been
rehearsed at most 2 times
THEN update the number of rehearsals for that word
"
=goal>
isa study-words
count =n
context =context
!eval! (< (actr-time) *stop-it*)
=memory>
isa memory-token
name =name
name (!eval! (if (< (rehearsal-count-len-str =name) 2) =name))
context =context
==>
!eval! (update-rehearsals-len-str =name)
)
(parameters-fct 'rehearse-token-3 (list :effort *rehearse* :r .8))
(p rehearse-skip
"
IF the goal is to study words
and there is time left to study
THEN do nothing
"
=goal>
isa study-words
count =n
context =context
!eval! (< (actr-time) *stop-it*)
==>
)
(parameters-fct 'rehearse-skip (list :r .5 :effort *rehearse*))
(p attend-test
"
IF the goal is to recognize words
and there are words left
THEN mark the goal to probe the target item
"
=goal>
isa recognize-words
target nil
!eval! *items*
==>
=goal>
target t
)
(parameters-fct 'attend-test (list :a *encode*))
(p probe-token
"
IF the goal is to probe a target item
THEN place the item in the goal
"
=goal>
isa recognize-words
target t
==>
=goal>
target (!eval! (len-str-get-word))
)
(p accept-word
"
IF the goal is to recognize a word in
the current context
and there is a memory token of that
word in this context
THEN respond yes
and mark the goal as responded
"
=goal>
isa recognize-words
target =word
- target t
context =context
=token>
isa memory-token
name =word
context =context
==>
!eval! (len-str-analyze =word 'yes)
=goal>
target nil
)
(parameters-fct 'accept-word (list :effort *respond*))
(p reject-a-word-2
"
IF the goal is to recognize a word in
the current context
THEN respond no
and mark the goal as responed
"
=goal>
isa recognize-words
target =word
context =context
==>
!eval! (len-str-analyze =word 'no)
=goal>
target nil
)
(parameters-fct 'reject-a-word-2 (list :r .5 :effort *respond*))