;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; ACT-R model of the fan experiment
;;; designed to test the suppression theory
;;;
;;; Works with ACT-R  4.0 (2/6/97 or newer)
;;;
;;; interface coded by: Dan Bothell
;;;
;;; This file contains an ACT-R model that
;;; models the fan effect present in recognition 
;;; during the experiment designed to test 
;;; whether suppression can account for the fan effect.
;;; In the task the subject first learns several 
;;; person-location pairs.  The fan of 
;;; either the person or location is held at 2, and
;;; the fan of the other is either 2 or 4.
;;; Then, there is a recognition task.
;;; The subject is presented with a 
;;; person-location pair, and must respond yes
;;; or no as to whether or not it was one of the
;;; pairs learned.  The foils are constructed from
;;; the same objects and locations as the targets,
;;; and some of the items are presented more frequently
;;; during the recognition task.
;;;
;;; The memory of a set of pairs is encoded into
;;; the model.  The model simulates one recognition step, and
;;; there is a fuction which will present the model
;;; with the pairs to be judged.
;;; 
;;; A simple function call, and a WWW interface
;;; are included.
;;;
;;; To run the model through the recognition, call
;;; (do-interfere-fan n).  That will print
;;; out a chart of the average time to classify
;;; the pairs over n runs of the model.
;;;
;;; 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.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; This section contains the code to simulate 
;;; the experiment, present the interface,
;;; and display the results.  The ACT-R
;;; model is located farther down.


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

;; these are set by the interface to control the model

(defvar *lf*)
(defvar *v*)
(defvar *s*)
(defvar *i*)
(defvar *runs*)
(defvar *places*)
(defvar *people*)
(defvar *study-pairs*)
(defvar *target-pairs*)
(defvar *foil-pairs*)
(defvar *presentations*)
(defvar *indexes*)

(setf *lf* 0.773)
(setf *v* nil)
(setf *s* 2.50)
(setf *i* 1.197)
(setf *runs* 1)

;;; data for the model when person fan is 2 and place fan is
;;; either 2 or 4

(setf *places* '((a tunnel) (b cage) (c library) (d windmill) 
                 (e tower) (f factory) (g desert) (h bank) 
                 (-a cabin) (-b theatre) (-e tavern) (-f ranch)))

(setf *people* '((1 cowboy) (2 beggar) (3 soldier) (4 singer) (5 typist) (6 artist)
                 (7 grocer) (8 reporter) (9 biker) (10 doctor) (11 writer) (12 monk)
                 (-1 fireman) (-2 banker) (-9 broker)))

;;; the items in the list are: place index, person index, number of test trials in a block

(setf *study-pairs* '((a 1 5) (a 2 5) (a 3 1) (a 4 1) (b 1 1) (b 2 1 1) (b 5 1) (b 6 1) (c 5 1) (c 6 1)
                       (c 7 1) (c 8 1) (d 3 1) (d 4 1) (d 7 1) (d 8 1) (e 9 5) (e 10 1) (f 9 1) (f 11 1)
                       (g 11 1) (g 12 1) (h 10 1) (h 12 1) (-a -1 5) (-a -2 5) (-b -1 1) (-b -2 1)
                       (-e -9 5) (-f -9 1)))

;;; each item in the list specifies one test stimulus, and specifies
;;; in order the:
;;;  place person condition 
;;;
;;; conditions are one of
;;;  (f)aciliation
;;;  (i)nterference
;;;  (c)ontrol
;;;  (s)uppression
;;;  (h)igh
;;;  (m)ixed
;;;  (l)ow
;;; and a fan number, either 2 or 4

(setf *target-pairs* '((a 1 f4) (a 2 f4) (a 3 i4) (a 4 i4) (b 1 i4) (b 2 i4) 
                       (b 5 s4) (b 6 s4) (c 5 c4) (c 6 c4) (c 7 c4) (c 8 c4)
                       (d 3 s4) (d 4 s4) (d 7 c4) (d 8 c4) (e 9 f2) (e 10 i2) 
                       (f 9 i2) (f 11 s2) (g 11 c2) (g 12 c2) (h 10 s2) (h 12 c2)))

(setf *foil-pairs* '((a 5 m4) (a 6 m4) (a 7 m4) (a 8 m4) (a -1 h4) (a -2 h4)
                     (b 3 l4) (b 4 l4) (b 7 l4) (b 8 l4) (c 1 m4) (c 2 m4) 
                     (c 3 l4) (c 4 l4) (d 1 m4) (d 2 m4) (d 5 l4) (d 6 l4)
                     (e 11 m2) (e 12 m2) (e -9 h2) (f 10 l2) (f 12 l2) (g 9 m2)
                     (g 10 l2) (h 9 m2) (h 11 m2)))

;;; specify the word's presentation stats:
;;; person or place index, number of times that item is presented in a test block,
;;; fan of that item

(setf *presentations* '((a 12 4) (b 4 4) (c 4 4) (d 4 4) (e 6 2) (f 2 2) (g 2 2) (h 2 2)
                        (-a 12 4) (-b 4 4) (-e 6 2) (-f 2 2)
                        (1 6 2) (2 6 2) (3 2 2) (4 2 2) (5 2 2) (6 2 2) (7 2 2) (8 2 2)
                        (9 6 2) (10 2 2) (11 2 2) (12 2 2) (-1 6 2) (-2 6 2) (-9 6 2)))

;;; index into the results array of the condition markers

(setf *indexes* '((f2 0) (i2 1) (s2 2) (c2 3) (f4 4) (i4 5) (s4 6) (c4 7)
                  (h2 8) (m2 9) (l2 10) (h4 11) (m4 12) (l4 13)))


;;; description of the model

(defparameter *about-interfere-fan*
"
This file contains an ACT-R model that models the 
fan effect present in recognition during the experiment
designed to test whether suppression can account for
the fan effect.  In the task the subject first learns 
several person-location pairs.  The fan of either the 
person or location is held at 2, and the fan of the 
other is either 2 or 4.  Then, there is a recognition 
task.  The subject is presented with a 
person-location pair, and must respond yes or no as 
to whether or not it was one of the pairs learned.
The foils are constructed from the same objects and
locations as the targets, and some of the items are 
presented more frequently than others during the 
recognition task.

The memory of a set of pairs is encoded into the model.
The model simulates one recognition step, and there is a 
fuction which will present the model with the pairs 
to be judged.
")

(defparameter *interfere-fan-data* (make-array '(14 2) :initial-contents '((1.33 1) (1.57 1) (1.43 1) (1.42 1)
                                                                          (1.42 1) (1.58 1) (1.51 1) (1.53 1)
                                                                          (1.51 1) (1.58 1) (1.59 1) 
                                                                          (1.60 1) (1.67 1) (1.70 1))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; 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 "New Experiment (Interference or Suppression?) Model" 2)

        (:hidden :sy *places* ((a tunnel) (b cage) (c library) (d windmill) 
                               (e tower) (f factory) (g desert) (h bank) 
                               (-a cabin) (-b theatre) (-e tavern) (-f ranch)))
        
        (:hidden :sy *people* ((1 cowboy) (2 beggar) (3 soldier) (4 singer) (5 typist) (6 artist)
                               (7 grocer) (8 reporter) (9 biker) (10 doctor) (11 writer) (12 monk)
                               (-1 fireman) (-2 banker) (-9 broker)))
        
        (:hidden :sy *study-pairs* ((a 1 5) (a 2 5) (a 3 1) (a 4 1) (b 1 1) (b 2 1 1) (b 5 1) (b 6 1) (c 5 1) (c 6 1)
                                    (c 7 1) (c 8 1) (d 3 1) (d 4 1) (d 7 1) (d 8 1) (e 9 5) (e 10 1) (f 9 1) (f 11 1)
                                    (g 11 1) (g 12 1) (h 10 1) (h 12 1) (-a -1 5) (-a -2 5) (-b -1 1) (-b -2 1)
                                    (-e -9 5) (-f -9 1)))
        
        
        (:hidden :sy *target-pairs* ((a 1 f4) (a 2 f4) (a 3 i4) (a 4 i4) (b 1 i4) (b 2 i4) 
                                     (b 5 s4) (b 6 s4) (c 5 c4) (c 6 c4) (c 7 c4) (c 8 c4)
                                     (d 3 s4) (d 4 s4) (d 7 c4) (d 8 c4) (e 9 f2) (e 10 i2) 
                                     (f 9 i2) (f 11 s2) (g 11 c2) (g 12 c2) (h 10 s2) (h 12 c2)))
        
        (:hidden :sy *foil-pairs* ((a 5 m4) (a 6 m4) (a 7 m4) (a 8 m4) (a -1 h4) (a -2 h4)
                                   (b 3 l4) (b 4 l4) (b 7 l4) (b 8 l4) (c 1 m4) (c 2 m4) 
                                   (c 3 l4) (c 4 l4) (d 1 m4) (d 2 m4) (d 5 l4) (d 6 l4)
                                   (e 11 m2) (e 12 m2) (e -9 h2) (f 10 l2) (f 12 l2) (g 9 m2)
                                   (g 10 l2) (h 9 m2) (h 11 m2)))
        
        
        (:hidden :sy *presentations* ((a 12 4) (b 4 4) (c 4 4) (d 4 4) (e 6 2) (f 2 2) (g 2 2) (h 2 2)
                                      (-a 12 4) (-b 4 4) (-e 6 2) (-f 2 2)
                                      (1 6 2) (2 6 2) (3 2 2) (4 2 2) (5 2 2) (6 2 2) (7 2 2) (8 2 2)
                                      (9 6 2) (10 2 2) (11 2 2) (12 2 2) (-1 6 2) (-2 6 2) (-9 6 2)))
        
        
        (:hidden :sy *indexes* ((f2 0) (i2 1) (s2 2) (c2 3) (f4 4) (i4 5) (s4 6) (c4 7)
                                (h2 8) (m2 9) (l2 10) (h4 11) (m4 12) (l4 13)))
        
        (:table)
        
        (:table)
        "F (latency scale) (s): "                    (:string :sy *lf*  0.773)  (:new-row)
        "I (intercept, min .6) (s): "                (:string :sy *i*   1.197)  (:new-row)
        "S (base log probability): "                 (:string :sy *s*   2.50) (:new-row) 
        "number of runs (1 - 20): "                  (:string :sy *runs* 1) 
        (:table-end)
        
        (:table)
        (:checkbox "Trace" :sy *v*  nil)
        (:table-end)
        (:table-end)
       
        (:new-para)
        (:button "Show Experiment Results" "(progn 
                                            (format *standard-output* \"~%~%Experimental data:~%\")
                                            (output-interfere-fan *interfere-fan-data*))")
        (:new-para)
        (:button "Run model" "(if (and (numberp *i*) (numberp *s*) (numberp *lf*) (numberp *runs*))
                                  (do-interfere-fan (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)")
        (:button "About Model" "(format *standard-output* \"~%~A~%\" *about-interfere-fan*)")
        (:new-para)
        "NOTE:"
        (:new-para)
        "- the choice between retrieving by person and retrieving by location is 
         random, so the system matches the foil times only on average over multiple
         runs."
        (: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 130k (90 pages) in size"
        (:new-para)))




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; do-interfere-fan takes one parameter, times, and prints out the average of 
;;; times runs over the items.
;;; Note: the choice between retrieving by person and retrieving
;;; by location is random and so the system matches the foil times 
;;; only on average over many runs

(defun do-interfere-fan (times) 
  (let ((rts (make-array '(14 2) :initial-element  0 )))

    (dotimes (i times)

      (dolist (x *target-pairs*)
        (incf (aref rts (second (assoc (third x) *indexes*)) 0 ) 
              (test-interfere-fan (second (assoc (second x) *people*))
                                  (second (assoc (first x) *places*))))
        (incf (aref rts (second (assoc (third x) *indexes*)) 1)))

      (dolist (x *foil-pairs*)
        (incf (aref rts (second (assoc (third x) *indexes*)) 0) 
              (test-interfere-fan (second (assoc (second x) *people*))
                                  (second (assoc (first x) *places*))))
        (incf (aref rts (second (assoc (third x) *indexes*)) 1))))
      
    (format *standard-output* "~%~%Parameters for run: (~S ~S ~S ~S)" *lf* *i* *s* times) 
    (format *standard-output* "~%~%Simulation data:~%")
    (output-interfere-fan rts)))


;;;;;;;;;;;;;;;;;;;
;;;
;;; output-interfere-fan takes one parameters,
;;; an array of response times and the number of runs
;;; that generated those times
;;; and prints out the table of the results

(defun output-interfere-fan (rts)

    (format *standard-output* "~%Response times (sec.):~%")
    (format *standard-output* "                       Fan 2      Fan 4~%")
    (format *standard-output* "Targets~%")
    (format *standard-output* "        Faciliation   ~6,3F~11,3F~%" (/ (aref rts 0 0) (aref rts 0 1)) (/ (aref rts 4 0) (aref rts 4 1)))
    (format *standard-output* "        Interference  ~6,3F~11,3F~%" (/ (aref rts 1 0) (aref rts 1 1)) (/ (aref rts 5 0) (aref rts 5 1)))
    (format *standard-output* "        Suppression   ~6,3F~11,3F~%" (/ (aref rts 2 0) (aref rts 2 1)) (/ (aref rts 6 0) (aref rts 6 1)))
    (format *standard-output* "        Control       ~6,3F~11,3F~%" (/ (aref rts 3 0) (aref rts 3 1)) (/ (aref rts 7 0) (aref rts 7 1)))
    (format *standard-output* "Foils~%")
    (format *standard-output* "        High          ~6,3F~11,3F~%" (/ (aref rts 8 0) (aref rts 8 1)) (/ (aref rts 11 0) (aref rts 11 1)))
    (format *standard-output* "        Mixed         ~6,3F~11,3F~%" (/ (aref rts 9 0) (aref rts 9 1)) (/ (aref rts 12 0) (aref rts 12 1)))
    (format *standard-output* "        Low           ~6,3F~11,3F~%" (/ (aref rts 10 0) (aref rts 10 1)) (/ (aref rts 13 0) (aref rts 13 1))))

    

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       
;;; test-interfere-fan runs 1 trial, with the stimuli given in p and l
;;; and the time of the run is returned

(defun test-interfere-fan (p l)
  
  (reset)
  (set-interfere-fan-params)

  (mod-chunk goal person nil location nil)
  (mod-chunk-fct 's1 (list 'second p 'sixth l))
  
  (goal-focus goal) 
  (run))

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; set-interfere-fan-params sets the parameters for a run based
;;; on the global variables 
;;; and adds all of the necessary chunks to memory
;;; for the study items, and sets the parameters
;;; for those chunks
;;;

(defun set-interfere-fan-params ()
  (sgp-fct (list 
            :era t
            :er t
            :LF *lf* 
            :act t
            :le 1 
            :v *v*))
   
  (parameters-fct 'match (list :effort (- (max .6 *i*) .6)))
  (parameters-fct 'not-location (list :effort (- (max .6 *i*) .6)))
  (parameters-fct 'not-person (list :effort (- (max .6 *i*) .6)))
  
  (dolist (x *places*)
    (let* ((concept (second x))
           (meaning (intern (concatenate 'string (string concept) "*"))))
      (addwm-fct (list (list concept 'isa 'word 'meaning meaning)
                       (list meaning 'isa 'meaning 'word concept)))
      (setgeneralbaselevels-fct (list (list concept 0) (list meaning 0)))))
  
  (dolist (x *people*)
    (let* ((concept (second x))
           (meaning (intern (concatenate 'string (string concept) "*"))))
      (addwm-fct (list (list concept 'isa 'word 'meaning meaning)
                       (list meaning 'isa 'meaning 'word concept)))
      (setgeneralbaselevels-fct (list (list concept 0) (list meaning 0)))))

  (let ((ialist nil))
    
    (dolist (x *study-pairs*)
      (let* ((person (second (assoc (second x) *people*)))
             (place (second (assoc (car x) *places*)))
             (nprop (third x))
             (nperson (second (assoc (second x) *presentations*)))
             (nplace (second (assoc (car x) *presentations*)))
             (person-wme (intern (concatenate 'string (string person) "*")))
             (place-wme (intern (concatenate 'string (string place) "*")))
             (prop (car (no-output (addwm-fct (list (list (gentemp "PROP") 'isa 'proposition
                                                          'relation 'in* 'arg1 person-wme
                                                          'arg2 place-wme)))))))
        
        
        (setf ialist (cons (list person-wme prop (+ *s* (log (/ nprop nperson)) )) ialist))
        (setf ialist (cons (list place-wme prop (+ *s* (log  (/ nprop nplace)))) ialist))
        (setf ialist (cons (list 'in* prop 0) ialist))))
    
    (set-ia-fct ialist)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; The ACT-R model of the recognition phase of 
;;; Fan Experiment


(clearall)

(sgp-fct (list  :era t :LF *lf* :act t :v nil :er t :le 1))

;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; CHUNK TYPES
;;;

(chunk-type proposition 
"
 a chunk type to represent the statement:
   arg1 relation arg2 (example captain in park)
"
 relation arg1 arg2)

(chunk-type sentence 
"
 a chunk type to hold a 6 word sentence
 of the form:
     A subject IS preposition THE place
"
 first second third fourth fifth sixth)

(chunk-type process-sentence 
"
 a chunk type to hold a goal to 
 process a sentence
  slots:
     person - holds the word for the person
              from the sentence (or nil if not yet read)
     location - holds the word for the location
              from the sentence (or nil if not yet read)
     sentence - the sentence to process
     pm - the meaning of the word in the person slot
     lm - the meaning of the word in the location slot
"
person location sentence pm lm)

(chunk-type recognize-goal
"
 a chunk type for a goal to try to recognize
 the association person relation location
  slots:
     person - holds the meaning chunk of a person
     location - holds the meaning chunk of a location
     relation - holds the meaning chunk of a relation
                between person and location
     pp - holds the meaning chunk of a person for
          a retrieved assiciation pp relation pl
     pl - holds the meaning chunk of a location 
          for a retrieved association pp relation pl
"
 person location relation pl pp)

(chunk-type word 
"
 a chunk type to hold words (used for display)
 with a slot containing the meaning chunk
"
 meaning)

(chunk-type meaning 
"
 a chunk type used to represent the meaning
 for a word, the word is in the word slot
"
 word)

;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; CHUNKS
;;;

(add-dm (in isa word meaning in*) (in* isa meaning word in)
        (is isa word meaning is*) (is* isa meaning word is)
        (the isa word)
        (a isa word)
        (goal isa process-sentence sentence s1)
        (s1 isa sentence first a third is fourth in fifth the))


;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; set the base level activations to 0 (B = 0)
;;; for the words - people, places, and prepositions
 
(setgeneralbaselevels
 (in 0)(in* 0)
 (the 0)
 (a 0)
 (s1 2.1)
 (goal 2))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; PRODUCTIONS
;;;

(p read-person
"
   IF the goal is to process a sentence and the person has 
      not been read yet
   THEN note the second word of the sentence in the goal as the person
"
   =goal>
      isa process-sentence
      person nil
      sentence =sentence

   =sentence>
      isa sentence
      second =word
==>
   =goal>
      person =word
)

(parameters read-person :effort .15)


(p read-location
"
   IF the goal is to process a sentence and the location has 
      not been read yet
   THEN note the sixth word of the sentence in the goal as the location
"
   =goal>
      isa process-sentence
      location nil
      sentence =sentence

   =sentence>
      isa sentence
      sixth =word
==>
   =goal>
      location =word
)

(parameters read-location :effort .15)


(p understand-person
"
   IF the goal is to process a sentence, and the person has been
       read, but its meaning not found
   THEN store the meaning of the word in the goal
"
   =goal>
      isa process-sentence
      person =word
      pm nil

   =word>
      isa word
      meaning =m
==>
   =goal>
      pm =m
)

(parameters understand-person :effort .1 :strength 10)


(p understand-location
"
   IF the goal is to process a sentence, and the location has been
       read, but its meaning not found
   THEN store the meaning of the word in the goal
"
   =goal>
      isa process-sentence
      location =word
      lm nil

   =word>
      isa word
      meaning =m
==>
   =goal>
      lm =m
)

(parameters understand-location :effort .1 :strength 10)


(p recognize
"
   IF the goal is to process a sentence, and both the person and
      location meanings have been determined
   THEN set a new goal to attempt to remember the association
       the 'person' in the 'location'
"
   =goal>
      isa process-sentence
      pm =p
      lm =l
==>
   =newgoal>
      isa recognize-goal
      person =p
      relation in*
      location =l
    
   !focus-on! =newgoal
)


(p retrieve-sentence-p
"
   IF the goal is to recognize the association 'person' in 'location'
      and no location memory has yet been found
      and there is a memory with 'person' in somewhere
   THEN set the retrieved person and location in the goal to
      'person' and somewhere
"
   =goal>
      isa recognize-goal
      person =p
      location =l
       pl nil

   =prop>
      isa proposition
      relation in*
      arg1 =p
      arg2 =newl
==>
   =goal>
      pp =p
      pl =newl
)


(p retrieve-sentence-l
"
   IF the goal is to recognize the association 'person' in 'location'
      and no person memory has yet been found
      and there is a memory with someone in 'location'
   THEN set the retrieved person and location in the goal to
      someone and 'location'
"
   =goal>
      isa recognize-goal
      person =p
      location =l
      pp nil

   =prop>
      isa proposition
      relation in*
      arg1 =newp
      arg2 =l
==>
   =goal>
      pp =newp
      pl =l
)


(p not-person
"
   IF the goal is to recognize the association 'person' in 'location'
      and a memory has been recalled
      and the person is not correct
   THEN respond no
      and pop the goal, finishing the trial
"
   =goal>
      isa recognize-goal
      person =p
      location =l
    - pp =p
      pl =l
==>
   !output! ("no")

   !pop!
)

(parameters-fct 'not-person (list :effort (- (max .6 *i*) .6)))


(p not-location
"
   IF the goal is to recognize the association 'person' in 'location'
      and a memory has been recalled
      and the location is not correct
   THEN respond no
      and pop the goal, finishing the trial
"
   =goal>
      isa recognize-goal
      person =p
      location =l
      pp =p
    - pl =l
==>
   !output! ("no")

   !pop!
)

(parameters-fct 'not-location (list :effort (- (max .6 *i*) .6)))


(p match
"
   IF the goal is to recognize the association 'person' in 'location'
      and a memory has been recalled
      and the memory has both 'person' and 'location'
   THEN respond yes
      and pop the goal, finishing the trial
"
   =goal>
      isa recognize-goal
      location =l
      pl =l
      person =p
      pp =p
==>
   !output! ("yes")

   !pop!
)

(parameters-fct 'match (list :effort (- (max .6 *i*) .6)))