;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;
;;; 2-Arm Maze choice model
;;; works with ACT-R 4.0 (2/6/97 or newer)
;;;
;;;
;;; This file contains an ACT-R model
;;; of the Devenport et al. animal
;;; choice experiment.
;;;
;;; In the experiment rats were exposed to
;;; a 2-armed maze.  For 18 trials they experienced
;;; alternating successes of arm A and failures of arm B.
;;; Then, after a 30 minute delay, they experienced
;;; 6 trials of alternating successes of arm B and
;;; failures of arm A.
;;; Rats in different conditions were then given a single
;;; test trial after a delay.  The delay varied across
;;; conditions as follows: 5, 25, 60, 210, 360, 2880 minutes
;;; In the small delay conditions rats preferred (exclusively)
;;; arm B which had been recently more successful.
;;; In the longer delay conditions rats preferred (almost
;;; exclusively) arm A which had been globally more successful
;;; in a 18:6 ratio.  The cross-over point occurred at
;;; approximately 210 minutes of delay.
;;;
;;; These results emphasize the greater weighting of recent
;;; successes/failures to distant (in time) successes/failures.
;;;
;;; Note:
;;; This model takes the basic unit of time to be minutes, instead of
;;; seconds.  When that is changed to seconds, the model still fits 
;;; the data with a slightly higher decay rate (+1).

;;; A command line interface,
;;; and a WWW interface are included.
;;;
;;; To use the command line interface,
;;; set the parameters with setf, and then
;;; call (devenport n) to simulate n subjects
;;; per condition.
;;;
;;; To use the WWW interface, you need to run
;;; the ACT-R on the Web application (follow the
;;; instructions provided with it), or use a
;;; web browser to connect to a site that has
;;; the model installed.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Global Variables


;;; the rest are the parameters for the model, and are set by the interfaces

(defvar *choice-g*)
(defvar *egt*)
(defvar *v*)
(defvar *text*)
(defvar *graphic*)
(defvar *overlay*)
(defvar *pl-decay*)
(defvar *arm-chosen-runs*)

(setf *text* t)
(setf *graphic* nil)
(setf *overlay* nil)
(setf *choice-g* 3.00)
(setf *egt* 0.24)
(setf *v* nil)
(setf *pl-decay* 4.61)
(setf *arm-chosen-runs* 100)

(defvar *actr-arm*)

;;delay conditions (in minutes) 5, 25, 60, 210, 360, 2880
(defparameter *devenport-data* '(1.0 1.0 1.0 .38 .13 .13))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; 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 "Devenport et al. animal choice Experiment Model" 2)
        (:table)

        (:table)
        "Decay rate: "                 (:string :sy *pl-decay*        4.61)  (:new-row)
        "Noise (t): "        (:string :sy *egt*            0.24)  (:new-row)
        "Runs per condition (max 1000): "  (:string :sy *arm-chosen-runs* 100)
        (: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)
        (:hidden :sy *choice-g*       3.00)  
        
        (:new-para)
        (:button "Show Experiment Results" "(display-devenport *devenport-data* nil)")
        (:new-para)
        (:button "Run model" "(if (and (numberp *choice-g*) (numberp *egt*) (numberp *pl-decay*) (numberp *arm-chosen-runs*))
                                  (devenport (min 1000 (max *arm-chosen-runs* 1)))
                                  (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 about 1 minute for a run of 100 per condition"
        (:new-line)
        "- The trace of 1 run of 100 per condition is approximatly 50k (30 page) in size"))




;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; devenport takes one parameter which specifies how many subjects per condition
;;;  First, the ACT-R parameters are set according to the values given in
;;; the global variables (as set by the interface). Then, the model is called to
;;; do one test trial n times for each condition, and each arm chosen is recorded.
;;; After all of the trials have been done a summary of the experiment results
;;; is displayed.

(defun devenport (n)
  (let ((result nil)
        (armB-chosen 0))


    (dolist (delays '(5 25 60 210 360 2880))

      (setf armB-chosen 0)

      (dotimes (i n)

        (reset)

        (sgp-fct (list     :ol nil
                           :era t
                           :er t
                           :mt nil
                           :lt nil
                           :ut nil
                           :pl *pl-decay*
                           :g  *choice-g*
                           :egs (/ *egt* (sqrt 2))
                           :v *v*))



        (spp choose-arm-A
                 :creation-time 0.0
                 :effort 0.01
                 :successes (0.6 1.8 3.0 4.2 5.4 6.6 7.8 9.0 10.2 11.4 12.6 13.8 15.0 16.2 17.4 18.6 19.8 21.0)
                 :failures (51.6 52.84 54.0 55.2 56.4 57.6)
                 :eventual-successes (0.6 1.8 3.0 4.2 5.4 6.6 7.8 9.0 10.2 11.4 12.6 13.8 15.0 16.2 17.4 18.6 19.8 21.0)
                 :eventual-failures (51.6 52.84 54.0 55.2 56.4 57.6))

        (spp choose-arm-B
                 :creation-time 0.0
                 :effort 0.01
                 :successes (52.2 53.4 54.6 55.8 57.0 58.2)
                 :failures (1.2 2.4 3.6 4.8 6.0 7.2 8.4 9.6 10.8 12 13.2 14.4 15.6 16.8 18.0 19.2 20.4 21.6)
                 :eventual-successes (52.2 53.4 54.6 55.8 57.0 58.2)
                 :eventual-failures (1.2 2.4 3.6 4.8 6.0 7.2 8.4 9.6 10.8 12 13.2 14.4 15.6 16.8 18.0 19.2 20.4 21.6))

        (actr-time-fct (+ 58.8 delays))

        (wmfocus goal)
        (run)
        (when (=  *actr-arm* 1 ) (incf armB-chosen)))

        (setf result (cons (/ armB-chosen n) result)))

      (format *standard-output* "~%~%Simulation parameters: (~S ~S ~S)~%" *pl-decay* *egt*  n)

      (display-devenport (reverse result) t))

)


;;; display-devenport 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 % choice for arm B,
;;; in either text, a graph (on the web),
;;; or both, depending on the settings of *text* and *graphic*

(defun display-devenport (data simulation)

  (when *text*
    (format *standard-output* "~%~%~a data:~%" (if simulation "Simulation" "Experimental"))
    (format t "~%       delay in mins        arm B chosen~%")
    (do ((x data (cdr x))
         (p '(5 25 60 210 360 2880) (cdr p)))
        ((null x))
      (format *standard-output* "         ~7,1F              ~9,3F~%" (car p) (car x)))

    (format *standard-output* "~%")

    (when (and simulation *overlay*)
      (format *standard-output* "~%~%Experimental data:~%")
    (format t "~%       delay in mins        arm B chosen~%")
      (do ((x *devenport-data* (cdr x))
           (p '(5 25 60 210 360 2880) (cdr p)))
          ((null x))
        (format *standard-output* "         ~7,1F              ~9,3F~%" (car p) (car x)))

      (format *standard-output* "~%"))

    (unless *graphic* (format *standard-output*
                              "~%</pre>If your browser supports JAVA, you
                               can display the data in a graph by checking
                               the Graphic output box on the interface page.<pre>~%~%")))
  (when *graphic*
    (format *standard-output* "
        <applet
        code = \"DansGraphs.class\"
        width = 500
        height = 400>

        <PARAM name=\"title\" value=\"Data for Devenport et al\">
        <PARAM name=\"longestline\" value=\"6\">
        <PARAM name=\"numlines\" value=\"~S\">
        <PARAM name=\"xmin\" value=\"0\">
        <PARAM name=\"xmax\" value=\"5\">
        <PARAM name=\"ymax\" value=\"1.0\">
        <PARAM name=\"ymin\" value=\"0\">
        <PARAM name=\"ydiv\" value=\".1\">
        <PARAM name=\"numxlabels\" value=\"6\">
        <PARAM name=\"xlabels\" value=\"5;25;60;210;360;2880;\">
        <PARAM name=\"widestxlabel\" value=\"WWWW\">
        <PARAM name=\"yspacing\" value=\"0.2\">
        <PARAM name=\"xval0\" value=\"0;1;2;3;4;5;\">
        <PARAM name=\"xname\" value=\"Delay (minutes)\">
        <PARAM name=\"yname\" value=\"Arm B chosen\">
        <PARAM name=\"lcolor0\" value=\"0\">
        <PARAM name=\"lstyle0\" value=\"~s\">
        <PARAM name=\"name0\" value=\"~a\">"
            (if (and simulation *overlay*) 2 1)
            (if simulation 2 6553)
            (if simulation "Simulation Data" "Experiment Data")
            )

    (format *standard-output* "<PARAM name=\"yval0\" value=\"")

    (dotimes (i 6)
      (format *standard-output* "~f;" (nth i data)))

    (format *standard-output* "\">")

    


    (when (and *overlay* simulation)
      (format *standard-output* "
        <PARAM name=\"lcolor1\" value=\"0\">
        <PARAM name=\"lstyle1\" value=\"6553\">
        <PARAM name=\"xval1\" value=\"0;1;2;3;4;5;\">
        <PARAM name=\"yval1\" value=\"")

      (dotimes (i 6)
        (format *standard-output* "~f;" (nth i *devenport-data*)))

      (format *standard-output* "\">
          <PARAM name=\"name1\" value=\"Experiment Data\">"))

      

    (format *standard-output* "
             <HR> Your browser does not support JAVA, so you cannot view the graphs.~%
             </HR></applet>")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; The rest of the file contains the
;;; actual ACT-R model to choose an arm of the maze on the single test trial.
;;; There are 2 productions, one to choose arm A, and
;;; one to choose arm B.  When the goal is set to
;;; choose an arm, either one can fire.  The one which
;;; fires is based on the (noisy) PG-C values for the productions.
;;; The two productions' histories of success/failure are set up to
;;; represent the training of the rats in this experiment (see description above).
;;;

(clearall)

(sgp :g 3.0 :era t :egs .17 :pl 4.0)

(chunk-type get-food arm "The type for the only goal")

(add-dm (goal
        "The goal is to get food"
        isa get-food)
        )

(p choose-arm-A
"
   IF the goal is to get food
   THEN begin travelling down arm A
"
   =goal>
      isa get-food
==>
  !pop!
  !output! ("~%chose: arm A  ~%")
  !eval! (setf *actr-arm* 0)
)

(p choose-arm-B
"
   IF the goal is to get food
   THEN begin travelling down arm B
"
   =goal>
      isa get-food
==>
  !pop!
  !output! ("~%chose: arm B  ~%")
  !eval! (setf *actr-arm* 1)
)