Notes on Methodology Overview Model 1: A Propositional Model of Medical Diagnosis

A Model of Addition

Page Under Development

The model of categorisation developed earlier is not particular plausible from a psychological perspective. It was developed primarily to demonstrate how to use some of the basic features. In this section we develop a model of multi-column addition. The model still leaves much to be desired from a psychological perspective, but it does have some psychological virtues. It also illustrates a number of further aspects of the COGENT modelling environment.

The Box/Arrow Diagram

The basic situation addressed by the model is subject performance when presented visually with an addition problem. The addition problem is assumed to be presented on paper, and the subject is able to use the paper as an "external buffer" onto which intermediate results may be writen. The model therfore includes a buffer corresponding to the paper.

We are not interested in modelling the processes of reading or comprehending the problem, or of those of writing the answer of intermediate results. We thus include a single input/output process in order to perform these functions.

The input/output process can read and write to the paper. Its rules are triggered by messages from a box simulating the addition process. This box in addition makes use of a short-term storage facility (working memory) for storing information on current goals/subgoals and partial results. The complete diagram is as below:

Box/Arrow diagram of the addition model

Exercise: Create a new research programme and draw the diagram as given above.

The Paper: An External Buffer

We begin fleshing out the model by specifying the initial contents of the paper. In order to do this, we must represent the numbers to be added in a uniform/consistent format. Almost any consistent representation would be adequate, but for readability we will represent each number in the addition problem by a term of the form row(N) where N is the number. Thus, we might start with the following intial contents:

Element: Number to add
row(45)

Element: Number to add
row(139)

Element: Number to add
row(14)

Element: Number to add
row(98)

Element: And one more very big number!
row(203918)

This represents the following addition problem:

45+
139
14
98
203918

For the present purposes we are representing only the numbers, not their positions in the sum.

Input/Output: An Interface Process

Input/Output mediates between the model of the subject and the paper. As such, it has two distinct functions: 1) it must "copy" relevant bits of the addition problem into the subject's Working Memory; and 2) it must "write" column totals and carry information onto the paper. We'll use separate sets of rules for the two functions. In order to write the rules for either function we must settle on a representation for information in Working Memory.

We'll begin with the process of reading a column of digits into Working Memory, and assume that this task is triggered by a message sent to Input/Output. [This is not the only option. The process could, for example, be triggered by the appearence of an appropriate element in Working Memory.]

Rule (unrefracted): Read a column of digits into working memory
TRIGGER: read_column(N)
IF: row(Number) is in Paper
get_digit_in_nth_position(Number, N, D)
THEN: add digit(D) to Working Memory

Rule (unrefracted): Note when there are no more columns to read
TRIGGER: read_column(N)
IF:
not row(Number) is in Paper
get_digit_in_nth_position(Number, N, _)
THEN: add last_column to Working Memory

Rule (unrefracted): Read any digits carried over from addition of previous columns
TRIGGER: read_column(N)
IF: carry(N, C) is in Paper
THEN: add digit(C) to Working Memory

Condition Definition: get_digit_in_nth_position/3: given a number like 382 and a position like 2, extract the 8
get_digit_in_nth_position(Number, Position, Digit) :-
Position > 1
Number > 9
NNumber is floor(Number / 10)
PPosition is (Position) - (1)
get_digit_in_nth_position(NNumber, PPosition, Digit)
get_digit_in_nth_position(Number, 1, Digit) :-
get_units_digit(Number, Digit)

Condition Definition: get_units_digit/2: Get the left-most digit in a number
get_units_digit(Number, Digit) :-
Digit is Number - 10 * floor(Number / 10)

Now consider the process of writing the result of adding one column to Paper. There are two separate tasks: 1) writing the new digit; and 2) annoting the next column with any value to be carried. Again, both of these require consideration of representational issues.

The representation of carry information was resolved above, so the write_carry operation is straightfoward. Assuming that the rule is triggered by a message of the form write_carry(C, N), where C is the amount of the carry and N is the current column, we have:

Rule (unrefracted): If we need to carry to the next column, write the carry on the paper
TRIGGER: write_carry(C, N)
IF: C>0
Column is (N) + (1)
THEN: add carry(Column, C) to Paper

Note that we only write the carry if it is non-zero, and it can't be negative, so in fact we only write the carry if it is greater than zero. The condition C>0 is obtained by following the pull-down menus along the path Add Condition/term comparison/arithmetic/is greater than. We also have to be sure that we write the carry in the appropriate column, i.e. the column to the left of the current column. The condition Column is (N) + (1) is obtained by following the pull-down menus along the path Add Condition/arithmetic/plus.

We shall represent the answer as an integer embedded with the Prolog functor answer, e.g., answer(243). This is a very readable representation, but it makes the rules a little complex. Basically, when we are part way through the problem we will have an answer such as answer(43) (possible representing the sum of the first two columns). On learning that the sum of the third column comes to 2, this must be changed to answer(243). An appropriate rule is:

Rule (unrefracted): Write an answer for a column onto the paper (incorporating existing partial answer)
TRIGGER: write_sum(S, N)
IF: answer(A) is in Paper
P is 10 to the power N - 1
NA is A + S * P
THEN: add answer(NA) to Paper
delete answer(A) from Paper

This rule is triggered by a message of the form write_sum(S, N) where S is the (units digit of the) sum of the digits in the N column. If N is 3, then S represents 100s. If N is 4, then S represents 1000s. The use of the power function works out the correct multiplier for S. Once multiplied and added to the previous (partial) answer, the new answer can be written in place of the old.

This rule is fine provided we have a partial answer on the paper. We also need the following rule to handle the case were we don't have an existing answer:

Rule (unrefracted): Write an answer for a column onto the paper (no existing partial answer)
TRIGGER: write_sum(S, N)
IF:
not answer(A) is in Paper
P is 10 to the power N - 1
NA is S * P
THEN: add answer(NA) to Paper

These rules are triggered by the same message pattern, but both rules should not fire at the same time because their conditions are mutually exclusive.

Exercise: Enter these rules and condition definitions, and an appropriate description, into Input/Output.

Working Memory

Short term store for goals and partial results

Class: Buffer/Propositional
Properties:
Initialise:Each Trial
Decay:None
Decay Constant:20
Limited Capacity:No
Capacity:7
On Excess:Random
Duplicates:Yes
Access:Random

Description: None
Initial Contents:

Element: We know that our initial goal is to add some numbers
goals([add])

Current Contents:

 69:	goals([process_column(8), next_column(8)]).
 65:	last_column.


Addition Rules

Rules & Condition Definitions:

Rule (refracted): Decompose add goal
IF: goals([add|Tail]) is in Working Memory
THEN: delete goals([add|Tail]) from Working Memory
add goals([process_column(1), next_column(1)|Tail]) to Working Memory

Rule (refracted): Decompose process_column goal
IF: goals([process_column(N)|Tail]) is in Working Memory
THEN: delete goals([process_column(N)|Tail]) from Working Memory
add goals([read_column(N), add_column(N), split_answer(N), write_answer(N)|Tail]) to Working Memory

Rule (refracted): Stop when there are no more columns
IF: goals([process_column(N)|Tail]) is in Working Memory
last_column is in Working Memory
THEN: stop

Rule (refracted): Move to the next column
IF: goals([next_column(N)|Tail]) is in Working Memory
N1 is (N) + (1)
THEN: delete goals([next_column(N)|Tail]) from Working Memory
add goals([process_column(N1), next_column(N1)|Tail]) to Working Memory

Rule (refracted): Read a column and initialise the sum
IF: goals([read_column(N)|Tail]) is in Working Memory
THEN: send read_column(N) to Input/Output
add sum(0) to Working Memory

Rule (refracted): read_column is complete
IF: goals([read_column(N)|Tail]) is in Working Memory
sum(X) is in Working Memory
THEN: delete goals([read_column(N)|Tail]) from Working Memory
add goals(Tail) to Working Memory

Rule (unrefracted): Add the next digit in the current column
IF: goals([add_column(N)|_]) is in Working Memory
sum(X) is in Working Memory
once digit(D) is in Working Memory
Y is (X) + (D)
THEN: delete digit(D) from Working Memory
delete sum(X) from Working Memory
add sum(Y) to Working Memory

Rule (refracted): We've finished adding ...
IF: goals([add_column(N)|Tail]) is in Working Memory
not digit(_) is in Working Memory
THEN: delete goals([add_column(N)|Tail]) from Working Memory
add goals(Tail) to Working Memory

Rule (refracted): Split the answer into tens and units
IF: goals([split_answer(N)|Tail]) is in Working Memory
sum(S) is in Working Memory
tens_and_units(S, T, U)
THEN: delete goals([split_answer(N)|Tail]) from Working Memory
add goals(Tail) to Working Memory
delete sum(S) from Working Memory
add sum(U) to Working Memory
add carry(T) to Working Memory

Condition Definition: tens_and_units/3: Split an answer into tens and units
tens_and_units(X, 0, X) :-
X < 10
tens_and_units(X, T, Y) :-
X >= 10
X1 is (X) - (10)
tens_and_units(X1, T1, Y)
T is (T1) + (1)

Rule (refracted): Write the answer (units and carry) on the paper via Input/Output
IF: goals([write_answer(N)|Tail]) is in Working Memory
sum(S) is in Working Memory
carry(C) is in Working Memory
THEN: delete goals([write_answer(N)|Tail]) from Working Memory
add goals(Tail) to Working Memory
delete sum(S) from Working Memory
delete carry(C) from Working Memory
delete column([]) from Working Memory
send write_sum(S, N) to Input/Output
send write_carry(C, N) to Input/Output


Condition editor within the addition model

Notes on Methodology Overview Model 1: A Propositional Model of Medical Diagnosis