;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ACT-R model of multicolumn addition ;;; using a visual-object representation, ;;; but not using the visual interface to ;;; construct the representation from the display. ;;; ;;; Works with ACT-R 4.0 (2/6/97 or newer) ;;; ;;; This file contains an ACT-R model that ;;; can perform addition of two numbers. ;;; ;;; A simple function call and a WWW interface ;;; are included. ;;; ;;; To have the model add 2 numbers, call ;;; the function actr-add with the numbers to be ;;; added: (actr-add 123 789). ;;; ;;; ;;; 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 create the ;;; representation of a problem, present the interface, ;;; and display the results. The ACT-R ;;; model is located farther down. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Global variables ;; these are used to create the visual-objects from the input numbers (defparameter *addition-order* '(ones tens hundreds thousands ten-thousands hundred-thousands)) (defparameter *addition-number-names* '(zero one two three four five six seven eight nine)) (defvar *addition-answer*) ; used to store the 'key-presses' made by the model ;; the rest are the parameters set in the interfaces (defvar *number1*) (defvar *number2*) (defvar *v* nil) (defparameter *addition-description* "ACT-R model of multicolumn addition.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; 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 "Addition Model" 2) (:table) (:table) "Addend 1" (:string :sy *number1* 12345) (:new-row) "Addend 2" (:string :sy *number2* 67890) (:table-end) (:table) (:checkbox "Trace" :sy *v* nil) (:table-end) (:table-end) (:new-para) (:button "Run Model" ) (:button "Production Rules" ) (:button "Chunk types" ) (:button "Chunks" ) (: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 5k (3 pages) in size")) (defun run-model (button-name) (cond ((string-equal button-name "Run Model" (if (and (numberp *number1*) (numberp *number2*)) (actr-add-numbers) (format *standard-output* \"Both addents must be numbers~%\")))) ((string-equal button-name "Production Rules") (let ((prods (no-output (pp)))) (dolist (x prods) (pp-fct (list x)) (spp-fct (list x)) (format *standard-output* "~%")))) ((string-equal "Chunk types" (wm))) ((string-equal "Chunks" (dm))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; This section contains the code to create the visual objects, ;;; and call the model. ;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; actr-add takes 2 numbers, and then calls the function which ;;; creates the visual objects for those numbers, and runs the ;;; model to add them. The numbers must have the same number of ;;; digits, and be 5 or fewer digits long. (defun actr-add (num1 num2) (setf *number1* num1) (setf *number2* num2) (actr-add-numbers)) ;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; actr-add-numbers is called to set up the visual objects, add a goal to working memory, ;;; focus on the goal, and then call run to start the model. ;;; The numbers that will be added are those in the global variables *number1* and *number2*. ;;; The 2 numbers that are to be added by the model must be the same length, and no more ;;; than 5 digits long. (defun actr-add-numbers () (reset) (sgp-fct (list :v *v*)) (let ((numstr1 (format nil "~a" *number1*)) (numstr2 (format nil "~a" *number2*))) (if (and (< (length numstr1) 6) (= (length numstr1) (length numstr2))) (progn (format *standard-output* "Solving Problem:~%~% ~S~%+ ~S~%" *number1* *number2*) (dotimes (i (+ 2 (length numstr1))) (format *standard-output* "-")) ;; clear the answer, and remove all visual objects from working memory (setf *addition-answer* nil) (deletewm-fct (no-output (swm isa visual-object))) ;; add the visual objects for the numbers to working memory (dotimes (i (length numstr1)) (let ((val1 (mod *number1* 10)) (val2 (mod *number2* 10))) (setf *number1* (truncate (/ *number1* 10))) (setf *number2* (truncate (/ *number2* 10))) (addwm-fct (list (list (gensym "vo") 'isa 'visual-object 'column (nth i *addition-order*) 'row 'top 'value (nth val1 *addition-number-names*)))) (addwm-fct (list (list (gensym "vo") 'isa 'visual-object 'column (nth i *addition-order*) 'row 'bottom 'value (nth val2 *addition-number-names*)))))) ;; add the + visual object to working memory (addwm-fct (list (list (gensym "vo") 'isa 'visual-object 'column (nth (length numstr1) *addition-order*) 'row 'bottom 'value '+))) ;; set the goal, and call the model (modwme goal column nil carry nil) (WMFocus goal) (run) ;; output the answer 'typed' by the model (when *v* (format *standard-output* "~%Solution:~%~% ~a~%+ ~a~%" numstr1 numstr2) (dotimes (i (+ 2 (length numstr1))) (format *standard-output* "-"))) (format *standard-output* (if (= (length *addition-answer*) (length numstr1)) "~% " "~% ")) (dolist (key *addition-answer*) (format *standard-output* "~S" key)) (format *standard-output* "~%")) ;; if the input is not valid, inform the user (format *standard-output* "Must use equal length numbers of 5 or fewer digits for the addends.")))) ;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; store-key-press takes one parameter, which should be the number ;;; 'pressed' by the model. The number is stored so the answer can be reported ;;; when the model finishes (defun store-key-press-addition (which-key) (setf *addition-answer* (cons which-key *addition-answer*))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; The ACT-R model (clearall) ;;;;;;;;;;;;; ;;; ;;; Define the chunk types for the model ;;; chunk types to represent the goals in the task (chunk-type add-column " a goal to add the two numbers in a column slots: number1 - the top number of the column number2 - the bottom number of the column carry - a possible carry from the previous column note - specifies if there is a carry to the next column, or if the problem is complete answer - holds the sum of the numbers in the column column - holds the index of the column currently being added " number1 number2 carry note answer column) (chunk-type addition-problem " a goal to solve an addition problem slots: column - column holds nil if the problem has not been started, otherwise it holds the column index of the next column to add carry - a value to carry to the next column " column carry) ;;; chunk types to represent the numbers and the addition facts (chunk-type addition-fact " a chunk type to represent addend1 + addend2 = sum " addend1 addend2 sum) (chunk-type number " an abstract representation of numbers slots: tens - the tens digit number wme value - the numerical value (i.e. 1 or 2 or 3 ...) units - the ones digit number wme " tens value units) ;;; chunk types to represent the columns and the ordering (chunk-type index " a chunk type to represent the column names ") (chunk-type next-info " a chunk type that specifies column index ordering slots: before - the index that occurs before the index in slot after after - the index that occurs after the index in slot before " before after) ;;; general chunk types needed for running the model (chunk-type visual-object " a chunk type to represent the visual locations of the numbers in the problem slots: row - the row (top or bottom) of a number column - the column index of the number value - the number chunk of the number " row column value) (chunk-type symbol " general symbols ") ;;;;;;;;;;;;;;;;;; ;;; ;;; Initialize the working memory for the model ;;; (add-dm ;; label markers for the columns of an addition problem (ones isa index) (tens isa index) (hundreds isa index) (thousands isa index) (ten-thousands isa index) (hundred-thousands isa index) (millions isa index) ;; labels for the row information of the visual-objects (top isa index) (bottom isa index) ;; general symbols used in the model (finished isa symbol) (+ isa symbol) ;; wmes to indicate the ordering of the column labels (n1 isa next-info before ones after tens) (n2 isa next-info before tens after hundreds) (n3 isa next-info before hundreds after thousands) (n4 isa next-info before thousands after ten-thousands) (n5 isa next-info before ten-thousands after hundred-thousands) (n6 isa next-info before hundred-thousands after millions) ;; Memory elements to encode the visual representation of the ;; addition problem: ;; 2 9 3 ;; + 1 2 5 (i1 isa visual-object column ones row top value three) (i2 isa visual-object column ones row bottom value five) (i3 isa visual-object column tens row top value nine) (i4 isa visual-object column tens row bottom value two) (i5 isa visual-object column hundreds row top value two) (i6 isa visual-object column hundreds row bottom value one) (i8 isa visual-object column thousands row bottom value +) ;;; wmes to represent the numbers 0-19 (zero isa number value 0 tens zero units zero) (one isa number value 1 tens zero units one) (two isa number value 2 tens zero units two) (three isa number value 3 tens zero units three) (four isa number value 4 tens zero units four) (five isa number tens zero value 5 units five) (six isa number tens zero value 6 units six) (seven isa number tens zero value 7 units seven) (eight isa number tens zero value 8 units eight) (nine isa number tens zero value 9 units nine) (ten isa number tens one units zero value 0) (eleven isa number tens one units one) (twelve isa number tens one units two) (thirteen isa number tens one units three) (fourteen isa number tens one units four) (fifteen isa number tens one units five) (sixteen isa number tens one units six) (seventeen isa number tens one units seven) (eightteen isa number tens one units eight) (nineteen isa number tens one units nine) ;;; Addition facts for all sums [0-10] + [0-10] ;;; and 1 + [11-18] (fact00 isa addition-fact addend1 zero addend2 zero sum zero) (fact01 isa addition-fact addend1 zero addend2 one sum one) (fact02 isa addition-fact addend1 zero addend2 two sum two) (fact03 isa addition-fact addend1 zero addend2 three sum three) (fact04 isa addition-fact addend1 zero addend2 four sum four) (fact05 isa addition-fact addend1 zero addend2 five sum five) (fact06 isa addition-fact addend1 zero addend2 six sum six) (fact07 isa addition-fact addend1 zero addend2 seven sum seven) (fact08 isa addition-fact addend1 zero addend2 eight sum eight) (fact09 isa addition-fact addend1 zero addend2 nine sum nine) (fact10 isa addition-fact addend1 one addend2 zero sum one) (fact11 isa addition-fact addend1 one addend2 one sum two) (fact12 isa addition-fact addend1 one addend2 two sum three) (fact13 isa addition-fact addend1 one addend2 three sum four) (fact14 isa addition-fact addend1 one addend2 four sum five) (fact15 isa addition-fact addend1 one addend2 five sum six) (fact16 isa addition-fact addend1 one addend2 six sum seven) (fact17 isa addition-fact addend1 one addend2 seven sum eight) (fact18 isa addition-fact addend1 one addend2 eight sum nine) (fact19 isa addition-fact addend1 one addend2 nine sum ten) (fact20 isa addition-fact addend1 two addend2 zero sum two) (fact21 isa addition-fact addend1 two addend2 one sum three) (fact22 isa addition-fact addend1 two addend2 two sum four) (fact23 isa addition-fact addend1 two addend2 three sum five) (fact24 isa addition-fact addend1 two addend2 four sum six) (fact25 isa addition-fact addend1 two addend2 five sum seven) (fact26 isa addition-fact addend1 two addend2 six sum eight) (fact27 isa addition-fact addend1 two addend2 seven sum nine) (fact28 isa addition-fact addend1 two addend2 eight sum ten) (fact29 isa addition-fact addend1 two addend2 nine sum eleven) (fact30 isa addition-fact addend1 three addend2 zero sum three) (fact31 isa addition-fact addend1 three addend2 one sum four) (fact32 isa addition-fact addend1 three addend2 two sum five) (fact33 isa addition-fact addend1 three addend2 three sum six) (fact34 isa addition-fact addend1 three addend2 four sum seven) (fact35 isa addition-fact addend1 three addend2 five sum eight) (fact36 isa addition-fact addend1 three addend2 six sum nine) (fact37 isa addition-fact addend1 three addend2 seven sum ten) (fact38 isa addition-fact addend1 three addend2 eight sum eleven) (fact39 isa addition-fact addend1 three addend2 nine sum twelve) (fact40 isa addition-fact addend1 four addend2 zero sum four) (fact41 isa addition-fact addend1 four addend2 one sum five) (fact42 isa addition-fact addend1 four addend2 two sum six) (fact43 isa addition-fact addend1 four addend2 three sum seven) (fact44 isa addition-fact addend1 four addend2 four sum eight) (fact45 isa addition-fact addend1 four addend2 five sum nine) (fact46 isa addition-fact addend1 four addend2 six sum ten) (fact47 isa addition-fact addend1 four addend2 seven sum eleven) (fact48 isa addition-fact addend1 four addend2 eight sum twelve) (fact49 isa addition-fact addend1 four addend2 nine sum thirteen) (fact50 isa addition-fact addend1 five addend2 zero sum five) (fact51 isa addition-fact addend1 five addend2 one sum six) (fact52 isa addition-fact addend1 five addend2 two sum seven) (fact53 isa addition-fact addend1 five addend2 three sum eight) (fact54 isa addition-fact addend1 five addend2 four sum nine) (fact55 isa addition-fact addend1 five addend2 five sum ten) (fact56 isa addition-fact addend1 five addend2 six sum eleven) (fact57 isa addition-fact addend1 five addend2 seven sum twelve) (fact58 isa addition-fact addend1 five addend2 eight sum thirteen) (fact59 isa addition-fact addend1 five addend2 nine sum fourteen) (fact60 isa addition-fact addend1 six addend2 zero sum six) (fact61 isa addition-fact addend1 six addend2 one sum seven) (fact62 isa addition-fact addend1 six addend2 two sum eight) (fact63 isa addition-fact addend1 six addend2 three sum nine) (fact64 isa addition-fact addend1 six addend2 four sum ten) (fact65 isa addition-fact addend1 six addend2 five sum eleven) (fact66 isa addition-fact addend1 six addend2 six sum twelve) (fact67 isa addition-fact addend1 six addend2 seven sum thirteen) (fact68 isa addition-fact addend1 six addend2 eight sum fourteen) (fact69 isa addition-fact addend1 six addend2 nine sum fifteen) (fact70 isa addition-fact addend1 seven addend2 zero sum seven) (fact71 isa addition-fact addend1 seven addend2 one sum eight) (fact72 isa addition-fact addend1 seven addend2 two sum nine) (fact73 isa addition-fact addend1 seven addend2 three sum ten) (fact74 isa addition-fact addend1 seven addend2 four sum eleven) (fact75 isa addition-fact addend1 seven addend2 five sum twelve) (fact76 isa addition-fact addend1 seven addend2 six sum thirteen) (fact77 isa addition-fact addend1 seven addend2 seven sum fourteen) (fact78 isa addition-fact addend1 seven addend2 eight sum fifteen) (fact79 isa addition-fact addend1 seven addend2 nine sum sixteen) (fact80 isa addition-fact addend1 eight addend2 zero sum eight) (fact81 isa addition-fact addend1 eight addend2 one sum nine) (fact82 isa addition-fact addend1 eight addend2 two sum ten) (fact83 isa addition-fact addend1 eight addend2 three sum eleven) (fact84 isa addition-fact addend1 eight addend2 four sum twelve) (fact85 isa addition-fact addend1 eight addend2 five sum thirteen) (fact86 isa addition-fact addend1 eight addend2 six sum fourteen) (fact87 isa addition-fact addend1 eight addend2 seven sum fifteen) (fact88 isa addition-fact addend1 eight addend2 eight sum sixteen) (fact89 isa addition-fact addend1 eight addend2 nine sum seventeen) (fact90 isa addition-fact addend1 nine addend2 zero sum nine) (fact91 isa addition-fact addend1 nine addend2 one sum ten) (fact92 isa addition-fact addend1 nine addend2 two sum eleven) (fact93 isa addition-fact addend1 nine addend2 three sum twelve) (fact94 isa addition-fact addend1 nine addend2 four sum thirteen) (fact95 isa addition-fact addend1 nine addend2 five sum fourteen) (fact96 isa addition-fact addend1 nine addend2 six sum fifteen) (fact97 isa addition-fact addend1 nine addend2 seven sum sixteen) (fact98 isa addition-fact addend1 nine addend2 eight sum seventeen) (fact99 isa addition-fact addend1 nine addend2 nine sum eightteen) (fact100 isa addition-fact addend1 ten addend2 zero sum ten) (fact101 isa addition-fact addend1 ten addend2 one sum eleven) (fact102 isa addition-fact addend1 ten addend2 two sum twelve) (fact103 isa addition-fact addend1 ten addend2 three sum thirteen) (fact104 isa addition-fact addend1 ten addend2 four sum fourteen) (fact105 isa addition-fact addend1 ten addend2 five sum fifteen) (fact106 isa addition-fact addend1 ten addend2 six sum sixteen) (fact107 isa addition-fact addend1 ten addend2 seven sum seventeen) (fact108 isa addition-fact addend1 ten addend2 eight sum eightteen) (fact109 isa addition-fact addend1 ten addend2 nine sum nineteen) (fact111 isa addition-fact addend1 eleven addend2 one sum twelve) (fact121 isa addition-fact addend1 twelve addend2 one sum thirteen) (fact131 isa addition-fact addend1 thirteen addend2 one sum fourteen) (fact141 isa addition-fact addend1 fourteen addend2 one sum fifteen) (fact151 isa addition-fact addend1 fifteen addend2 one sum sixteen) (fact161 isa addition-fact addend1 sixteen addend2 one sum seventeen) (fact171 isa addition-fact addend1 seventeen addend2 one sum eightteen) (fact181 isa addition-fact addend1 eightteen addend2 one sum nineteen) ;;; the main goal of the model (goal isa addition-problem)) ;;; focus on the main goal (goal-focus goal) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; PRODUCTIONS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (p start-problem " IF the goal is to do an addition problem but no column has been identified THEN set a subgoal to add the digits in the ones column note that the tens column ins the next one to work on and setup the note slot of the new goal to pass a value back to the carry slot of the current goal when popped " =goal> isa addition-problem column nil ==> =newgoal> isa add-column column ones note =carry carry zero =goal> column tens carry =carry !push! =newgoal ) (p read-number1 " IF the goal is to add the numbers in a column and the top number has not been read yet and there is a number in the top row of the column THEN note in the goal that this is one of the numbers to be added " =goal> isa add-column number1 nil column =col =object> isa visual-object value =num1 row top column =col ==> =goal> number1 =num1 ) (p read-number2 " IF the goal is to add the numbers in a column and the bottom number has not been read yet and there is a number in the bottom row of the column THEN note in the goal that this is one of the numbers to be added " =goal> isa add-column number2 nil column =col =object> isa visual-object value =num2 column =col row bottom ==> =goal> number2 =num2 ) (p add-numbers " IF the goal is to add the numbers in the column and both numbers have been read and another number is their sum THEN note that other number as the answer " =goal> isa add-column number1 =num1 number2 =num2 answer nil =fact> isa addition-fact addend1 =num1 addend2 =num2 sum =sum ==> =goal> answer =sum ) (p extract-answer " IF the goal is to add the numbers in the column and the sum has been computed and the sum has a ones digit and a tens digit THEN set the answer to the ones digit and note the tens digit as the carry " =goal> isa add-column answer =sum note nil carry zero =sum> isa number tens =num units =number1 ==> =goal> answer =number1 note =num ) (p process-carry " IF the goal is to add the numbers in the column and there is an answer and the column has a carry marked and there is a number one greater than the answer THEN note in the goal that the answer is the new number and remove the marking of the carry from the goal " =goal> isa add-column answer =number carry one =fact> isa addition-fact addend2 one addend1 =number sum =new ==> =goal> answer =new carry zero ) (p write-answer " IF the goal is to add the numbers in the column and there is no carry and the answer is a one-digit number THEN write the answer and pop the goal (returning the value of the note slot) " =goal> isa add-column carry zero answer =number column =col =number> isa number value =value tens zero ==> !output! ("the answer to column ~s is: ~s~%" =col =value) !eval! (store-key-press-addition =value) !pop! ) (p last-column-no-carry " IF the goal is add the numbers in a column and an item has been read into the bottom number slot and that item is a + and there is no carry to be passed on THEN note the goal as finished and pop it (passing the finished back to the carry slot of the previous goal) " =goal> isa add-column number2 + - carry one ==> =goal> note finished !pop! ) (p last-column-carry " IF the goal is to add the numbers in a column and an item has been read into the bottom number slot and that item is a + and there is a carry to be passed on THEN write the carry out and note the goal as finished and pop it (passing the finished back to the carry slot of the previous goal) " =goal> isa add-column number2 + carry one column =col carry =carrynum =carrynum> isa number value =val ==> !output! ("the answer to column ~s is: ~s~%" =col =val) !eval! (store-key-press-addition =val) =goal> note finished !pop! ) (p next-column " IF the goal is to do an addition problem and the problem has not been marked as finished and there is a column after this one THEN note that the current column is the one on which you are working and set a subgoal to add the digits in that column and note in the current goal which is the next column and setup the note slot of the new goal to pass a value back to the carry slot of the current goal when popped " =goal> isa addition-problem column =pos1 - carry finished carry =carry =next> isa next-info before =pos1 after =pos2 ==> =newgoal> isa add-column column =pos1 carry =carry note =newcarry =goal> column =pos2 carry =newcarry !push! =newgoal ) (p stop-problem " IF the goal is to do an addition problem and the problem has been marked as finished THEN pop the goal " =goal> isa addition-problem carry finished ==> !pop! )