;;;
;;; Reversal-shift learning, child model
;;; Use (do-it-kendler n) to run an experiment, with n the number of virtual subjects
;;; Model by Niels Taatgen
;;; n.a.taatgen@bcn.rug.nl
;;; http://tcw2.ppsw.rug.nl/~niels
;;;
;;;
;;; Lisp code to run experiments
;;;
(defvar *result* nil)
(defvar *status* 'initial)
(defvar *answer*)
(defvar *count* nil)
(defvar *v* nil)
(defvar *egs*)
(defvar *egs-s* 1.3)
(defvar *egs-f* 0.35)
(defvar *runs* 1)
(defparameter *kendler-exp-results* '(6.0 15.8 24.4 9.0))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; 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 "Kendler and Kendler Experiment Model" 2)
(:table)
(:table)
"Expected gain S (fast): " (:string :sy *egs-f* 0.35) (:new-row)
"Expected gain S (slow): " (:string :sy *egs-s* 1.3) (: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-kendler *kendler-exp-results* nil)")
(:new-para)
(:button "Run model" "(if (and (numberp *egs-f*) (numberp *egs-s*) (numberp *runs*))
(do-it-kendler (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 70k (40 pages) in size"
(:new-para)))
(defun add-success-kendler ()
(setf *result* '+))
(defun add-failure-kendler ()
(setf *result* '-))
(defun random-color-kendler ()
(nth (random 2) '(red green)))
(defun random-size-kendler ()
(nth (random 2) '(large small)))
(defun check-answer-kendler (color size)
(cond
((eq *status* 'initial)
(if (eq color 'red) 'yes 'no))
((eq *status* 'reversal)
(if (eq color 'green) 'yes 'no))
((eq *status* 'non-reversal)
(if (eq size 'large) 'yes 'no))))
(defun random-goal-kendler-f ()
(let ((color (random-color-kendler))
(size (random-size-kendler))
(ob1 (gentemp "O")))
(setf *answer* (check-answer-kendler color size))
(addwm-fct
(list (list ob1 'isa 'object)
(list (gentemp "P") 'isa 'property 'of ob1 'type 'psize 'value size)
(list (gentemp "P") 'isa 'property 'of ob1 'type 'pcolor 'value color)))
(addwm-fct
(list (list (gentemp "CAT") 'isa 'gen-goal-f 'object ob1)))))
(defun random-goal-kendler-s ()
(let ((color (random-color-kendler))
(size (random-size-kendler)))
(setf *answer* (check-answer-kendler color size))
(addwm-fct
(list (list (gentemp "CAT") 'isa 'gen-goal-s 'prop1 size 'prop2 color)))))
(defun do-random-kendler (which)
(setf *result* nil)
(wmfocus-fct (funcall which))
(run))
(defun do-ten-ok-kendler (which &optional (n 10)(x 0))
(if (and (> n 0) (< x 100))
(progn (do-random-kendler which)
(if (eq *result* '+)
(do-ten-ok-kendler which (- n 1)(+ x 1))
(do-ten-ok-kendler which 10 (+ x 1))))
x))
(defun do-reversal-experiment-kendler (n conditie which)
(setf *count* nil)
(let (res)
(dotimes (i n)
(reset)
(sgp-fct (list :era t :pl 0.5 :er t :ans 0.1 :egs *egs* :v *v*))
(setup-dependency-production-kendler which)
(setf *status* 'initial)
(setf res (- (do-ten-ok-kendler which) 10))
(when (not (= res 90))
(setf *status* conditie)
(setf res (- (do-ten-ok-kendler which) 10))
(when (not (= res 90))
(push res *count*))))))
(defun setup-dependency-production-kendler (which)
(if (equal which #'random-goal-kendler-f)
(pdisable-fct (list 'build-dependency))
(pdisable-fct (list 'pop-dependency))))
(defun do-it-kendler (n)
(let ((rev nil))
(setf *egs* *egs-f*)
(when *v*
(format *standard-output* "~%~%Fast child simulation of reversal:~%~%"))
(do-reversal-experiment-kendler n 'reversal #'random-goal-kendler-f)
(if *count*
(push (/ (apply #'+ *count*) (length *count*)) rev)
(push -1 rev))
(when *v*
(format *standard-output* "~%~%Fast child simulation of extra-dimensional:~%~%"))
(do-reversal-experiment-kendler n 'non-reversal #'random-goal-kendler-f)
(if *count*
(push (/ (apply #'+ *count*) (length *count*)) rev)
(push -1 rev))
(setf *egs* *egs-s*)
(when *v*
(format *standard-output* "~%~%Slow child simulation of reversal:~%~%"))
(do-reversal-experiment-kendler n 'reversal #'random-goal-kendler-s)
(if *count*
(push (/ (apply #'+ *count*) (length *count*)) rev)
(push -1 rev))
(when *v*
(format *standard-output* "~%~%Slow child simulation of extra-dimensional:~%~%"))
(do-reversal-experiment-kendler n 'non-reversal #'random-goal-kendler-s)
(if *count*
(push (/ (apply #'+ *count*) (length *count*)) rev)
(push -1 rev))
(display-kendler (reverse rev) t)))
(defun display-kendler (data simulation)
(format *standard-output* "~%~A Data:~%~%" (if simulation "Simulation" "Experimental"))
(when simulation
(format *standard-output* "Parameters for run: (~S ~S ~S)~%" *egs-s* *egs-f* *runs*))
(format *standard-output* "~%Mean Number of Trials to Criterion of 10 Correct Classification~%")
(format *standard-output* " Type of Transfer~%")
(format *standard-output* " Reversal Extra-Dimensional~%")
(format *standard-output* "Fast Child ~4,1f ~4,1f~%" (nth 0 data) (nth 1 data))
(format *standard-output* "Slow Child ~4,1f ~4,1f~%" (nth 2 data) (nth 3 data)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(clearall)
;;; Parameters
(sgp :era t ; rational analysis
:pl 0.5 ; parameters learning
:er t ; randomness enabled
:ans 0.1 ; activation noise
:egs 0.35 ; expected gain noise
)
(set-analogized-parameters :successes 10 :failures 0 :eventual-successes 10
:eventual-failures 0)
;;; Chunk-types
(chunk-type gen-goal-f object property answer ptype tried)
(chunk-type konstant)
(chunk-type property of type value)
(chunk-type property-type label)
(chunk-type object did-retry)
(chunk-type gen-goal-s prop1 prop2 answer)
(chunk-type tried object value)
;;; Initial declarative memory
(set-dm
(red isa konstant)
(green isa konstant)
(large isa konstant)
(small isa konstant)
(yes isa konstant)
(no isa konstant)
(t isa konstant)
(dont-know isa konstant)
(pcolor isa property-type label CL)
(psize isa property-type label SZ)
(CL isa konstant)
(SZ isa konstant))
;;;
;;; Start of productions
;;;
(p select-property-type
"
select a property of the task to focus on
this rule will compete with any learned rules
"
=goal>
isa gen-goal-f
property nil
ptype nil
=ptype>
isa property-type
==>
=goal>
ptype =ptype
)
(parameters select-property-type :r-alpha 20 :r-beta 2)
(p select-other-type
"
If a property is selected for which there is already a
dependency, try another.
The tried-flag prohibits endless loops.
This production has the failure-parameter set to T, since it marks
failure for the original selection.
"
=goal>
isa gen-goal-f
ptype =type
property nil
- tried t
=dependency>
isa dependency
specifics =type
=type>
isa property-type
label =l1
=newtype>
isa property-type
- label =l1
==>
=goal>
ptype =newtype
tried t
)
(parameters select-other-type :q-alpha 100 :q-beta 0 :r-alpha 100 :r-beta 0
:failure t)
(p create-property-dependencies
"
Create a dependency that is an example of retrieving the property
"
=goal>
isa gen-goal-f
object =object
property nil
ptype =label
=property>
isa property
of =object
type =label
value =value
==>
=goal>
property =value
tried nil
=oldgoal>
isa gen-goal-f
object =object
=newgoal>
isa gen-goal-f
object =object
property =value
ptype =label
=dependency>
isa dependency
goal =oldgoal
modified =newgoal
constraints =property
specifics =label
!push! =dependency
)
(parameters create-property-dependencies :r-alpha 10 :r-beta 50 :b-b 40 :b-v 40)
(p answer-dont-know-f
"
If there is no rule that can give an answer, give don't know as an answer
the dummy retrieval allows analogy to beat this production.
"
=goal>
isa gen-goal-f
- property nil
answer nil
=dummy>
isa konstant
==>
=goal>
answer dont-know
)
(parameters answer-dont-know-f :r-alpha 2 :r-beta 10)
(p evaluate-answer-correct-f
"
If the expected answer is equal to the real answer, pop with success.
"
=goal>
isa gen-goal-f
answer =answer
!eval! (equal =answer *answer*)
==>
!output! ("The answer is ~S, which is correct" =answer)
!eval! (add-success-kendler)
!pop!
)
(parameters evaluate-answer-correct-f :success t)
(p evaluate-answer-false-f
"
If the expected answer differs from the real answer, create a
dependency that is an example of giving the right answer.
"
=goal>
isa gen-goal-f
object =ob
property =prop
ptype =ptype
answer =answer
!eval! (not (equal =answer *answer*))
==>
=goal>
answer (!eval! *answer*)
!output! ("The answer given is ~S, but should have been ~S" =answer
*answer*)
!eval! (add-failure-kendler)
=oldgoal>
isa gen-goal-f
object =ob
property =prop
ptype =ptype
=dependency>
isa dependency
goal =oldgoal
modified =goal
specifics =prop
!focus-on! =dependency
)
(parameters evaluate-answer-false-f :failure t :r-alpha 100)
(p pop-dependency
=goal>
isa dependency
==>
!pop!
)
;;;
;;; Start of productions
;;;
(p answer-dont-know
"
If there is no rule that can give an answer, give don't know as an answer
the dummy retrieval allows analogy to beat this production.
"
=goal>
isa gen-goal-s
answer nil
==>
=goal>
answer dont-know
)
(parameters answer-dont-know :r-alpha 2 :r-beta 10)
(p evaluate-answer-correct
"
If the expected answer is equal to the real answer, pop with success.
"
=goal>
isa gen-goal-s
answer =answer
!eval! (equal =answer *answer*)
==>
!output! ("The answer is ~S, which is correct" =answer)
!eval! (add-success-kendler)
!pop!
)
(parameters evaluate-answer-correct :success t)
(p evaluate-answer-false
"
If the expected answer differs from the real answer, create a
dependency that is an example of giving the right answer.
"
=goal>
isa gen-goal-s
prop1 =p1
prop2 =p2
answer =answer
!eval! (not (equal =answer *answer*))
==>
!output! ("The answer given is ~S, but should have been ~S" =answer
*answer*)
!eval! (add-failure-kendler)
=goal>
answer (!eval! *answer*)
=dependency>
isa dependency
modified =goal
!focus-on! =dependency
)
(parameters evaluate-answer-false :failure t :r-alpha 100
:r-beta 100)
(p build-dependency
=dependency>
isa dependency
modified =end-goal
=end-goal>
isa gen-goal-s
prop1 =p1
prop2 =p2
answer =answer
==>
=start-goal>
isa gen-goal-s
prop1 =p1
prop2 =p2
=dependency>
goal =start-goal
specifics (!eval! (list =p1 =p2))
!pop!
)