;;;


(defvar *list*)
(setf *list* nil)
(defvar *output*)
(setf *output* nil)
(defvar *text* t)
(defvar *graphic* nil)
(defvar *v* nil)
(defvar *lf* 5)

(defvar *WWW-interface*)

(setf  *WWW-interface* 
      '((:heading "Rule Experiment" 2)
        (:table)
        (:table)
        "Latency Factor:" (:string :sy *lf* 5)
        (:table-end)
       
        (:table)
        (:checkbox "Trace" :sy *v*  nil) (:new-row)
        (:checkbox "Text output" :sy *text*  t) (:new-row)
        (:checkbox "Graphic output" :sy *graphic*  nil) 

        (:table-end)
        (:table-end)
       
        (:new-para)
        
        (:button "Run model" "
                              (if (and (numberp *lf*)
                                      )
                                  (cycle-rule)
                                  (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 to run the model"
        (:new-line)
        "- The trace of 1 run is approximatly 40k (25 pages) in size"
        (:new-para)))




(defun randmem-rule (lis) (nth (random (length lis)) lis))

(defun seedy-rule (name num)
  (no-output (let* ((relation (eval `(chunk-slot-value ,(car (eval `(sdm isa rule name ,name))) relation)))
         (chunk (randmem-rule (eval `(sdm isa fact relation ,relation))))
        (a (eval `(chunk-slot-value ,chunk arg1)))
        (b (eval `(chunk-slot-value ,chunk arg2)))
        (c (eval `(chunk-slot-value ,chunk ans))))
    (case  num
      (0 (list name a 'a b 'b))
      (1 (list name a 'a c 'c))
      (2 (list name b 'b c 'c))))))


(defun cycle-rule ()
  (let (a b c d)
  (reset)
  (do  ((temp '(adams brown smith jones) (cdr temp))
        (temp1 '(0 1 2 2) (cdr temp1))
        (result1 nil (cons (run-it-rule (car temp) (car temp1)) result1))
        (result2 nil (cons (run-it-rule (car temp) (car temp1)) result2)))
        ((null temp) (setf a (list result1 result2))))
  (reset)
  (do  ((temp '(adams brown smith jones) (cdr temp))
        (temp1 '(2 2 0 1) (cdr temp1))
        (result1 nil (cons (run-it-rule (car temp) (car temp1)) result1))
        (result2 nil (cons (run-it-rule (car temp) (car temp1)) result2)))
        ((null temp) (setf b (list result1 result2))))
(reset) (compile-productions-rule)
  (do  ((temp '(adams brown smith jones) (cdr temp))
        (temp1 '(0 1 2 0) (cdr temp1))
        (result1 nil (cons (run-it-rule (car temp) (car temp1)) result1))
        (result2 nil (cons (run-it-rule (car temp) (car temp1)) result2)))
        ((null temp) (setf c (list result1 result2))))
  (do  ((temp '(adams brown smith jones) (cdr temp))
        (temp1 '(2 2 0 1) (cdr temp1))
        (result1 nil (cons (run-it-rule (car temp) (car temp1)) result1))
        (result2 nil (cons (run-it-rule (car temp) (car temp1)) result2)))
        ((null temp) (setf d (list result1 result2))))
(reset) (compile-productions-rule)
  (analyze-data-rule (append a b c d))))

(defun analyze-data-rule (lis)
  (do ((temp lis (cdr temp))
       (result nil (cons (analyze1-rule (car temp)) result)))
      ((null temp) (output-data-rule (reverse result)))))

(defun output-data-rule (lis)
  (when *text*
    (format *standard-output* "          Latency (seconds)~%")
    (format *standard-output* "Condition                  Click~%")
    (format *standard-output* "                     1       2       3~%")
    
    (format *standard-output* "Initial Norm:    ~7,3f ~7,3f ~7,3f~%" (/ (+ (first (first lis)) (first (third lis))) 2.0)
            (/ (+ (second (first lis)) (second (third lis))) 2.0)
            (/ (+ (third (first lis)) (third (third lis))) 2.0))
    
    (format *standard-output* "Initial Prime:   ~7,3f ~7,3f ~7,3f~%" (/ (+ (first (second lis)) (first (fourth lis))) 2.0)
            (/ (+ (second (second lis)) (second (fourth lis))) 2.0)
            (/ (+ (third (second lis)) (third (fourth lis))) 2.0))
     
    (format *standard-output* "Practice Norm:   ~7,3f ~7,3f ~7,3f~%"  (first (fifth lis)) (second (fifth lis)) (third (fifth lis)))
     
    (format *standard-output* "Practice Prime:  ~7,3f ~7,3f ~7,3f~%"  (first (sixth lis)) (second (sixth lis)) (third (sixth lis)))
     
    (format *standard-output* "Reverse Norm:    ~7,3f ~7,3f ~7,3f~%"  (first (seventh lis)) (second (seventh lis)) (third (seventh lis)))
     
    (format *standard-output* "Reverse Prime:   ~7,3f ~7,3f ~7,3f~%"  (first (Eighth lis)) (second (eighth lis)) (third (eighth lis)))

    (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 = 300 
        height = 500> 
        <PARAM name=\"title\" value=\"Rule Experiment\">
        <PARAM name=\"xmin\" value=\"1\">
        <PARAM name=\"xmax\" value=\"3\">
        <PARAM name=\"ymax\" value=\"4.0\">
        <PARAM name=\"ymin\" value=\"1\">
        <PARAM name=\"ydiv\" value=\".25\">
        <PARAM name=\"yspacing\" value=\".5\">
        <PARAM name=\"xspacing\" value=\"1\">
        <PARAM name=\"xval0\" value=\"1;2;3;\">
        <PARAM name=\"xval1\" value=\"1;2;3;\">
        <PARAM name=\"xval2\" value=\"1;2;3;\">
        <PARAM name=\"xval3\" value=\"1;2;3;\">
        <PARAM name=\"xval4\" value=\"1;2;3;\">
        <PARAM name=\"xval5\" value=\"1;2;3;\">
        <PARAM name=\"xname\" value=\"Click\">
        <PARAM name=\"yname\" value=\"Latency (sec)\">
         <PARAM name=\"name0\" value=\"Initial Norm\">
         <PARAM name=\"name1\" value=\"Initial Prime\">
         <PARAM name=\"name2\" value=\"Practice Norm\">
         <PARAM name=\"name3\" value=\"Practice Prime\">
         <PARAM name=\"name4\" value=\"Reverse Norm\">
         <PARAM name=\"name5\" value=\"Reverse Prime\">
        <PARAM name=\"numlines\" value=\"6\">
        <PARAM name=\"longestline\" value=\"3\">
        <PARAM name=\"lcolor0\" value=\"0\">
        <PARAM name=\"lstyle0\" value=\"0\">
        <PARAM name=\"lcolor1\" value=\"0\">
        <PARAM name=\"lstyle1\" value=\"6553\">
        <PARAM name=\"lcolor2\" value=\"1\">
        <PARAM name=\"lstyle2\" value=\"0\">
        <PARAM name=\"lcolor3\" value=\"1\">
        <PARAM name=\"lstyle3\" value=\"6553\">
        <PARAM name=\"lcolor4\" value=\"2\">
        <PARAM name=\"lstyle4\" value=\"0\">
       <PARAM name=\"lcolor5\" value=\"2\">
        <PARAM name=\"lstyle5\" value=\"6553\">
        " )
    (format *standard-output* "<param name=\"yval0\" value=\"~7,3f;~7,3f;~7,3f;\">" (/ (+ (first (first lis)) (first (third lis))) 2.0)
            (/ (+ (second (first lis)) (second (third lis))) 2.0)
            (/ (+ (third (first lis)) (third (third lis))) 2.0))
    
    (format *standard-output* "<param name=\"yval1\" value=\"~7,3f;~7,3f;~7,3f;\">" (/ (+ (first (second lis)) (first (fourth lis))) 2.0)
            (/ (+ (second (second lis)) (second (fourth lis))) 2.0)
            (/ (+ (third (second lis)) (third (fourth lis))) 2.0))
     
    (format *standard-output* "<param name=\"yval2\" value=\"~7,3f;~7,3f;~7,3f;\">"  (first (fifth lis)) (second (fifth lis)) (third (fifth lis)))
     
    (format *standard-output* "<param name=\"yval3\" value=\"~7,3f;~7,3f;~7,3f;\">"  (first (sixth lis)) (second (sixth lis)) (third (sixth lis)))
     
    (format *standard-output* "<param name=\"yval4\" value=\"~7,3f;~7,3f;~7,3f;\">"  (first (seventh lis)) (second (seventh lis)) (third (seventh lis)))
     
    (format *standard-output* "<param name=\"yval5\" value=\"~7,3f;~7,3f;~7,3f;\">"  (first (Eighth lis)) (second (eighth lis)) (third (eighth lis)))

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



(defun analyze1-rule (lis)
  (do ((temp lis (cdr temp))
       (first 0 (+ (first (car temp)) first))
       (second 0 (+ (second (car temp)) second))
       (third 0 (+ (third (car temp)) third)))
      ((null temp) (list (/ first 4) (/ second 4) (/ third 4)))))

(defun compile-productions-rule ()
  (spp Retrieve-Ab :strength 1)(spp Retrieve-Ac :strength 1)(spp Retrieve-bc :strength 1)
(p output-slot1-1
   =goal>
      isa probe
      name adams
      slot1 =val
      role1 a
      slot2 nil
==>
    =subgoal>
       isa OUTPUT
       rule rule1
       slot =val
       role a
    =goal>
       rule rule1
       slot2 Ready
    !push! =subgoal
 )
(spp output-slot1-1 :b .5)

(p output-a-1
   =goal> 
      isa output
      rule rule1
      slot =val
      role a
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-a-1 :b .5 :effort 1)

(p output-b-1
   =goal> 
      isa output
      rule rule1
      slot =val
      role b
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-b-1 :b .5 :effort 1)

(p output-c-1
   =goal> 
      isa output
      rule rule1
      slot =val
      role c
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-c-1 :b .5 :effort 1)

   (p retrieve-1
    =goal>
       isa PROBE
       rule Rule1
       role1 a
       slot1 =val1
       role2 b
       slot2 =val2
       slot3 Ready
==>
   =subgoal>
     isa fact
     arg1 =val1
     arg2 =val2
     relation plus
      ans =ans
   =goal>
      slot3 =ans
      role3 c
!push! =subgoal)
(p output-slot1-2
   =goal>
      isa probe
      name brown
      slot1 =val
      role1 a
      slot2 nil
==>
    =subgoal>
       isa OUTPUT
       rule rule2
       slot =val
       role a
    =goal>
       rule rule2
       slot2 Ready
    !push! =subgoal
 )
(spp output-slot1-2 :b .5)

(p output-a-2
   =goal> 
      isa output
      rule rule2
      slot =val
      role a
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-a-2 :b .5 :effort 1)

(p output-b-2
   =goal> 
      isa output
      rule rule2
      slot =val
      role b
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-b-2 :b .5 :effort 1)

(p output-c-2
   =goal> 
      isa output
      rule rule2
      slot =val
      role c
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-c-2 :b .5 :effort 1)

   (p retrieve-2
    =goal>
       isa PROBE
       rule Rule2
       role1 a
       slot1 =val1
       role2 c
       slot2 =val2
       slot3 Ready
==>
   =subgoal>
     isa fact
     arg1 =val1
     arg2 =ans
     relation minus
      ans =val2
   =goal>
      slot3 =ans
      role3 b
!push! =subgoal)

(p output-slot1-3
   =goal>
      isa probe
      name smith
      slot1 =val
      role1 b
      slot2 nil
==>
    =subgoal>
       isa OUTPUT
       rule rule3
       slot =val
       role b
    =goal>
       rule rule3
       slot2 Ready
    !push! =subgoal
 )
(spp output-slot1-3 :b .5)

(p output-a-3
   =goal> 
      isa output
      rule rule3
      slot =val
      role a
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-a-2 :b .5 :effort 1)

(p output-b-3
   =goal> 
      isa output
      rule rule3
      slot =val
      role b
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-b-3 :b .5 :effort 1)

(p output-c-3
   =goal> 
      isa output
      rule rule3
      slot =val
      role c
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-c-3 :b .5 :effort 1)

   (p retrieve-3
    =goal>
       isa PROBE
       rule Rule3
       role1 b
       slot1 =val1
       role2 c
       slot2 =val2
       slot3 Ready
==>
   =subgoal>
     isa fact
     arg1 =ans
     arg2 =val1
     relation times
      ans =val2
   =goal>
      slot3 =ans
      role3 a
!push! =subgoal)

(p output-slot1-4
   =goal>
      isa probe
      name jones
      slot1 =val
      role1 b
      slot2 nil
==>
    =subgoal>
       isa OUTPUT
       rule rule4
       slot =val
       role b
    =goal>
       rule rule4
       slot2 Ready
    !push! =subgoal
 )
(spp output-slot1-4 :b .5)

(p output-a-4
   =goal> 
      isa output
      rule rule4
      slot =val
      role a
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-a-4 :b .5 :effort 1)

(p output-b-4
   =goal> 
      isa output
      rule rule4
      slot =val
      role b
==>
!output! ("~S in money" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-b-4 :b .5 :effort 1)

(p output-c-4
   =goal> 
      isa output
      rule rule4
      slot =val
      role c
==>
!output! ("~S in time" =val)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-c-4 :b .5 :effort 1)

   (p retrieve-4
    =goal>
       isa PROBE
       rule Rule4
       role1 a
       slot1 =val1
       role2 b
       slot2 =val2
       slot3 Ready
==>
   =subgoal>
     isa fact
     arg1 =val1
     arg2 =val2
     relation divide
      ans =ans
   =goal>
      slot3 =ans
      role3 c
!push! =subgoal)
(spp retrieve-1 :b .5)(spp retrieve-2 :b .5)(spp retrieve-3 :b .5)(spp retrieve-4 :b .5))

(defun run-it-rule (name num)
  (mod-chunk goal name nil slot1 nil slot2 nil slot3 nil role1 nil role2 nil role3 nil rule nil)
  (goal-focus goal)
  (setf *output* (list (actr-time )))
 (setf *list* (seedy-rule name num))
  (run)
  (do ((temp *output* (cdr temp))
       (result nil (cons (- (cadr temp) (car temp)) result)))
      ((null (cdr temp)) (reverse result))))

(defun get-pname-rule () (pop *list*))
(defun get-slot1-rule () (pop *list*))
(defun get-role1-rule () (pop *list*))
(defun get-role2-rule () (pop *list*))
(defun get-slot2-rule () (pop *list*))



(defun add-facts-rule ()
  (dolist (x  '((mtwo zero mtwo) (mtwo pfive m1pfive) (mtwo one mone) (mtwo 1pfive mpfive) (mtwo two zero)
                (m1pfive mpfive mtwo) (m1pfive zero m1pfive) (m1pfive pfive one) (m1pfive one mpfive)
                (m1pfive 1pfive zero) (m1pfive two pfive)
                (mone mone mtwo) (mone mpfive m1pfive) (mone zero mone) (mone pfive mpfive) (mone one zero)
                (mone 1pfive pfive) (mone two one)
                (mpfive mpfive mone) (mpfive zero mpfive) (mpfive pfive zero) (mpfive one pfive)
                (mpfive 1pfive one) (mpfive two 1pfive)
                (zero zero zero)(zero pfive pfive) (zero one one) (zero 1pfive 1pfive) (zero two two)
                (pfive pfive one) (pfive one 1pfive) (pfive 1pfive two)
                (one one two)))
    (add-dm-fct (list (list (gentemp "PLUS") 'isa 'fact 'arg1 (first x) 'arg2 (second x) 'relation 'plus 'ans (third x))
                      (list (gentemp "PLUS") 'isa 'fact 'arg2 (first x) 'arg1 (second x) 'relation 'plus 'ans (third x))
                      (list (gentemp "MINUS") 'isa 'fact 'arg1 (third x) 'arg2 (second x) 'relation 'minus 'ans (first x))
                      (list (gentemp "MINUS") 'isa 'fact 'arg2 (first x) 'arg1 (third x)  'relation 'plus 'ans (second x)))))
  
  (dolist (x '((mtwo mone two) (mtwo mpfive one) (mtwo zero zero) (mtwo pfive mone) (mtwo one mtwo)
               (m1pfive mone 1pfive) (m1pfive zero zero) (m1pfive one m1pfive)
               (mone mone one) (mone mpfive pfive) (mone zero zero) (mone pfive mpfive) (mone one mone) 
               (mone 1pfive m1pfive) (mone two mtwo)
               (mpfive zero zero) (mpfive one mpfive) (mpfive two mone)
               (zero zero zero) (zero pfive zero) (zero one zero) (zero 1pfive zero) (zero two zero)
               (pfive one pfive) (pfive two one) (one one one) (one 1pfive 1pfive) (one two two)))
    (add-dm-fct (list (list (gentemp "TIMES") 'isa 'fact 'arg1 (first x) 'arg2 (second x) 'relation 'times 'ans (third x))
                      (list (gentemp "TIMES") 'isa 'fact 'arg2 (first x) 'arg1 (second x) 'relation 'times 'ans (third x))
                      (list (gentemp "DIVIDE") 'isa 'fact 'arg1 (third x) 'arg2 (second x) 'relation 'divide 'ans (first x))
                      (list (gentemp "DIVIDE") 'isa 'fact 'arg2 (first x) 'arg1 (third x) 'relation 'divide 'ans (second x))))))

;AdamsÕ Rule; Money + Money = Money
;BrownÕs Rule: Time Š Time = Time
;SmithÕs Rule: Money * Time = Money
;JonesÕ Rule Time / Money = Time


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

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

(clearall)

(sgp-fct (list  :era t :bll .5 :ol nil :lf *lf* :v *v*))

(chunk-type probe name slot1 slot2 slot3 role1 role2 role3 rule)
(chunk-type fact arg1 arg2 relation ans)
(chunk-type rule name first second third fourth relation)
(chunk-type output rule slot role)
(chunk-type inverse reverse)

(add-dm (goal isa probe) (smith isa chunk) (ready isa chunk) (plus isa chunk)  (jones isa chunk)
        (times isa chunk) (a isa chunk) (b isa chunk) (c isa chunk) (mtwo isa chunk) (m1pfive isa chunk)
        (mone isa chunk) (mpfive isa chunk) (zero isa chunk) (pfive isa chunk) (one isa chunk)
        (1pfive isa chunk) (two isa chunk) (time isa chunk) (money isa chunk) (minus isa chunk) (divide isa chunk)
        (adams isa chunk) (brown isa chunk)
        (rule1 isa rule name adams first money second money third money relation plus)
        (rule2 isa rule name brown first time second time third time relation minus)
        (rule3 isa rule name Smith first money second time third money relation times)
        (rule4 isa rule name jones first time second money third time relation divide))

(add-facts-rule)

(sdp :references (-20 -60 -100 -140 -180 -220 -260 -300 -340 -380))
(goal-focus goal)

(p read-name
   =goal>
      isa probe
      name nil
==>
   =goal>
      name (!eval! (get-pname-rule)))

(spp read-name :effort .185)

(p read-slot1
   =goal>
      isa probe
      name =name
      slot1 nil
==>
   =goal>
      slot1 (!eval! (get-slot1-rule))
      role1 (!eval! (get-role1-rule)))

(spp read-slot1 :effort .185)

(p output-slot1-decl
   =goal>
      isa probe
      name =name
      slot1 =val
      role1 =role
      slot2 nil
   =rule>
      isa rule
      name =name
==>
   =subgoal>
      isa output
      rule =rule
      slot =val
      role =role
    =goal>
      rule =rule
      slot2 ready
!push! =subgoal)

(spp output-slot1-decl :a 2.0)

(p output-slot2-decl
   =goal>
      isa probe
      name =name
      slot2 =val
      role2 =role
      slot3 nil
      rule =rule
==>
   =subgoal>
      isa output
      rule =rule
      slot =val
      role =role
    =goal>
      slot3 ready
!push! =subgoal)

(spp output-slot2-decl :a 2.0)

(p output-a
   =goal> 
      isa output
      rule =rule
      slot =val
      role a
   =rule>
      isa rule
      first =type
==>
!output! ("~S in ~S" =val =type)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-a :effort 1)

(p output-b
   =goal> 
      isa output
      rule =rule
      slot =val
      role b
   =rule>
      isa rule
      second =type
==>
!output! ("~S in ~S" =val =type)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-b :effort 1)
(p output-c
   =goal> 
      isa output
      rule =rule
      slot =val
      role c
   =rule>
      isa rule
      third =type
==>
!output! ("~S in ~S" =val =type)
!eval! (setf *output* (append *output* (list (1+ (actr-time )))))
!pop!)

(spp output-c :effort 1)

(p read-slot2
   =goal>
      isa probe
      slot2 ready
==>
   =goal>
      slot2 (!eval! (get-slot2-rule))
      role2 (!eval! (get-role2-rule)))

(spp read-slot2 :effort .185)


(p calculate-slot3-ab
   =goal>
      isa probe
      rule =rule
      role1 a
      slot1 =val1
      role2 b
      slot2 =val2
      slot3 ready
   =rule>
      isa rule
      relation =relation
==>
   =subgoal>
     isa fact
     arg1 =val1
     arg2 =val2
     relation =relation
      ans =ans
   =goal>
      slot3 =ans
      role3 c
!push! =subgoal)

(p calculate-slot3-ac
   =goal>
      isa probe
      rule =rule
      role1 a
      slot1 =val1
      role2 c
      slot2 =val2
      slot3 ready
   =rule>
      isa rule
      relation =relation
==>
   =subgoal>
     isa fact
     arg1 =val1
     arg2 =ans
     relation =relation
      ans =val2
   =goal>
      slot3 =ans
      role3 b
!push! =subgoal)

(p calculate-slot3-bc
   =goal>
      isa probe
      rule =rule
      role1 b
      slot1 =val1
      role2 c
      slot2 =val2
      slot3 ready
   =rule>
      isa rule
      relation =relation
==>
   =subgoal>
     isa fact
     arg1 =ans
     arg2 =val1
     relation =relation
      ans =val2
   =goal>
      slot3 =ans
      role3 a
!push! =subgoal)

(p retrieve-ab
   =goal>
     isa fact
     arg1 =v1
     arg2 =v2
     relation =r
     ans nil
   =fact>
     isa fact
     arg1 =v1
     arg2 =v2
     relation =r
     ans =ans
==>
   =goal>
     ans =ans
!pop!)

(p retrieve-ac
   =goal>
     isa fact
     arg1 =v1
     arg2 nil
     relation =r
     ans =v2
   =fact>
     isa fact
     arg1 =v1
     arg2 =ans
     relation =r
     ans =v2
==>
   =goal>
     arg2 =ans
!pop!)

(p retrieve-bc
   =goal>
     isa fact
     arg1 nil
     arg2 =v1
     relation =r
     ans =v2
   =fact>
     isa fact
     arg1 =ans
     arg2 =v1
     relation =r
     ans =v2
==>
   =goal>
     arg1 =ans
!pop!)

(p output-slot3-decl
   =goal>
      isa probe
      rule =rule
      slot3 =val
      role3 =role
==>
   =subgoal>
      isa output
      rule =rule
      slot =val
      role =role
!focus-on! =subgoal)

(spp output-slot3-decl :a 2.0)