A Model of Addition Overview Model 1a: Elaborating the Experimental Environment

Model 1: A Propositional Model of Medical Diagnosis

The Task

The remainder of this tutorial examines a series of models of progressively increasing complexity which deal with the Medical Diagnosis task (Fox 1980).

In the human experimental version of the task, the subject plays the role of a doctor who is presented with a symptom and must reach a diagnosis. The subject may ask about any of five symptoms, and is then told whether that the symptom is or is not present. When the subject has collected enough symptom information, (s)he can offer a diagnosis, selected from five possible diseases. The experimenter then tells the subject if (s)he was correct, and if not, what the correct diagnosis was.

Symptoms are probabilistically associated with diseases, and in order to achieve a good level of performance the subject must learn these probabilities as the task progresses. It is the final feedback which allows the subject to learn the associations.

A propositional model of skilled performance on the Medical Diagnosis task

The box/arrow diagram for a COGENT model of the Medical Diagnosis task is shown below. The model includes submodels of the experimental environment (the Y-shaped formation on the left), and of the subject (the inverted L on the right)

The Subject

The subject corresponds to the three rightmost boxes in the above box/arrow diagram. The functions of these boxes are as follows:

The Decision Procedure process
uses the symptom information in Working Memory to generate new questions about symptoms, and to generate diagnoses, which it adds to Working Memory.
The Working Memory buffer
contains symptom information, questions and diagnoses as described above, as well as any intermediate information generated during the diagnosis process by the Decision Procedure.
The Input-Output process
simulates the processes of perception and communication; in the present case, this means it receives messages from the Experimenter (statements whether a given symptom is present or absent), which it adds to Working Memory, and sends information to the Experimenter (questions about symptoms, and finally a diagnosis), which it finds in Working Memory.

As can be seen from the diagram, the Input-Output and Decision Procedure processes have both read and write access to the Working Memory buffer.

At this point you should construct the box/arrow diagram, including all the boxes and arrows as shown in the figure above. Note that you will also need to open each box to add the labels; if you don't, you will experience difficulties when you add rules and conditions later.

The Decision Procedure process

When the box/arrow diagram is complete, you should construct the Decision Procedure. This is the most complex part of the model, and in this version involves a large number of rules.

First of all, it should be recalled that at the beginning of a trial, a message is sent to the subject stating that one of the five possible symptoms is present; this is then relayed by the Input-output process into Working Memory. So, one set of rules in the Decision Procedure wait for a buffer element of the form told(SymptomName, present) to appear in Working Memory. The rules for each symptom are given below, and each one operates in the same way: whenever the symptom information appears, and provided no diagnosis has already been made, the rule fires and adds information to Working Memory about diseases which might be suspected on the basis of this symptom information.

Rule (refracted): Expectations from dysphagia
IF:   told(dysphagia, present) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add diseases(tonsillitis, suspected) to Working Memory
      add diseases(laryngitis, suspected) to Working Memory

Rule (refracted): Expectations from vomiting
IF:   told(vomiting, present) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add diseases(meningitis, suspected) to Working Memory
      add diseases(hepatitis, suspected) to Working Memory

Rule (refracted): Expectations from pyrexia
IF:   told(pyrexia, present) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add diseases(meningitis, suspected) to Working Memory
      add diseases(hepatitis, suspected) to Working Memory
      add diseases(tonsillitis, suspected) to Working Memory
      add diseases(parotitis, suspected) to Working Memory

Rule (refracted): Expectations from headache
IF:   told(headache, present) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add diseases(meningitis, suspected) to Working Memory
      add diseases(tonsillitis, suspected) to Working Memory
      add diseases(laryngitis, suspected) to Working Memory

Rule (refracted): Expectations from earache
IF:   told(earache, present) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add diseases(meningitis, suspected) to Working Memory
      add diseases(tonsillitis, suspected) to Working Memory
      add diseases(parotitis, suspected) to Working Memory

All of the above rules are refracted, so they will only fire once at most per trial. The elements they add to Working Memory appear there on the next cycle, and are used in the next round of processing. The rules for this phase determine, on the basis of each suspected disease, which additional symptoms might be present.

Rule (refracted): The Stonsillitis rule
IF:   diseases(tonsillitis, suspected) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add expected(tonsillitis, pyrexia, present) to Working Memory
      add expected(tonsillitis, vomiting, absent) to Working Memory
      add expected(tonsillits, earache, present) to Working Memory
      add expected(tonsillitis, dysphagia, present) to Working Memory
      add expected(tonsillits, headache, present) to Working Memory

Rule (refracted): The Smeningitis rule
IF:   diseases(meningitis, suspected) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add expected(meningitis, headache, present) to Working Memory
      add expected(meningitis, pyrexia, present) to Working Memory
      add expected(meningitis, dysphagia, absent) to Working Memory
      add expected(meningitis, earache, present) to Working Memory
      add expected(meningitis, vomiting, present) to Working Memory

Rule (refracted): The Shepatitis rule
IF:   diseases(hepatitis, suspected) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add expected(hepatitis, earache, absent) to Working Memory
      add expected(hepatitis, vomiting, present) to Working Memory
      add expected(hepatitis, dysphagia, absent) to Working Memory
      add expected(hepatitis, pyrexia, present) to Working Memory
      add expected(hepatitis, headache, absent) to Working Memory

Rule (refracted): The Sparotitis rule
IF:   diseases(parotitis, suspected) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add expected(parotitis, vomiting, absent) to Working Memory
      add expected(parotitis, earache, present) to Working Memory
      add expected(parotitis, dysphagia, absent) to Working Memory
      add expected(parotitis, pyrexia, present) to Working Memory
      add expected(parotitis, headache, present) to Working Memory

Rule (refracted): The Slaryngitis rule
IF:   diseases(laryngitis, suspected) is in Working Memory
      not diagnosis_is(Disease) is in Working Memory
THEN: add expected(laryngitis, vomiting, absent) to Working Memory
      add expected(laryngitis, dysphagia, present) to Working Memory
      add expected(laryngitis, pyrexia, present) to Working Memory
      add expected(laryngitis, earache, absent) to Working Memory
      add expected(laryngitis, headache, present) to Working Memory

Having determined which symptoms are expected for each suspected disease, the next phase involves deciding which symptom to ask about. Two possible rules are:

Rule (refracted): The equivalent of the verify rule in Fox 1980
IF:   once expected(Disease, Symptom, present) is in Working Memory
           not told(Symptom, Value) is in Working Memory
THEN: add query(Symptom, present) to Working Memory

This first symptom selection rule simply asks for the first symptom which might confirm the first suspected disease. Note the use of the once qualifier to ensure that the rule fires only once on any given cycle. An alternative rule for symptom selection is

Rule (refracted): The equivalent of the discrim rule in Fox 1980
IF:   once expected(Disease1, Symptom, Value1) is in Working Memory
           expected(Disease2, Symptom, Value2) is in Working Memory
           not Value1 == Value2
           not told(Symptom, Value) is in Working Memory
THEN: add query(Symptom, present) to Working Memory

The second symptom selection rule attempts to ask about symptoms which discriminate between two suspected diseases. You should ensure that you use only one of these rules at a time --- one convenient way to do this is to enter them both and then Ignore one.

Whichever rule is used, the query which is added to Working Memory is forwarded by Input-Output to the Experimenter, which responds in due course; meanwhile however, the symptom query rule will continue to resatisfy on each subsequent cycle, generating queries for each relevant symptom. So far, then, all the model does is to ask about symptoms, so we need to add a final set of rules to make diagnoses on the basis of the incoming symptom information. The diagnosis rules are listed below.

Rule (refracted): The dtonsillitis rule
IF:   diseases(tonsillitis, suspected) is in Working Memory
      told(dysphagia, present) is in Working Memory
      told(earache, present) is in Working Memory
THEN: add diagnosis_is(tonsillitis) to Working Memory

Rule (refracted): The dtonsillitis (2) rule
IF:   diseases(tonsillitis, suspected) is in Working Memory
      told(dysphagia, present) is in Working Memory
      told(pyrexia, present) is in Working Memory
THEN: add diagnosis_is(tonsillitis) to Working Memory

Rule (refracted): The dlaryngitis rule
IF:   diseases(laryngitis, suspected) is in Working Memory
      told(dysphagia, present) is in Working Memory
      told(earache, absent) is in Working Memory
THEN: add diagnosis_is(laryngitis) to Working Memory

Rule (refracted): The dlaryngitis (2) rule
IF:   diseases(laryngitis, suspected) is in Working Memory
      told(dysphagia, present) is in Working Memory
      told(pyrexia, absent) is in Working Memory
THEN: add diagnosis_is(laryngitis) to Working Memory

Rule (refracted): The dparotitis rule
IF:   diseases(parotitis, suspected) is in Working Memory
      told(headache, absent) is in Working Memory
      told(earache, present) is in Working Memory
      told(dysphagia, absent) is in Working Memory
THEN: add diagnosis_is(parotitis) to Working Memory

Rule (refracted): The dparotitis (2) rule
IF:   diseases(parotitis, suspected) is in Working Memory
      told(pyrexia, absent) is in Working Memory
      told(earache, present) is in Working Memory
      told(dysphagia, absent) is in Working Memory
THEN: add diagnosis_is(parotitis) to Working Memory

Rule (refracted): The dmeningitis rule
IF:   diseases(meningitis, suspected) is in Working Memory
      told(headache, present) is in Working Memory
      told(pyrexia, present) is in Working Memory
      told(dysphagia, absent) is in Working Memory
THEN: add diagnosis_is(meningitis) to Working Memory

Rule (refracted): The dmening2 rule
IF:   diseases(meningitis, suspected) is in Working Memory
      told(vomiting, present) is in Working Memory
      told(headache, present) is in Working Memory
THEN: add diagnosis_is(meningitis) to Working Memory

Rule (refracted): The dmening2 rule (2)
IF:   diseases(meningitis, suspected) is in Working Memory
      told(vomiting, present) is in Working Memory
      told(earache, present) is in Working Memory
THEN: add diagnosis_is(meningitis) to Working Memory

Rule (refracted): The dhepatitis rule
IF:   diseases(hepatitis, suspected) is in Working Memory
      told(vomiting, present) is in Working Memory
      told(headache, absent) is in Working Memory
THEN: add diagnosis_is(hepatitis) to Working Memory

Rule (refracted): The dhepatitis (2) rule
IF:   diseases(hepatitis, suspected) is in Working Memory
      told(vomiting, present) is in Working Memory
      told(pyrexia, absent) is in Working Memory
THEN: add diagnosis_is(hepatitis) to Working Memory

It should be noted that the above rules are not in a one-to-one correspondence with possible diagnoses --- because of the probabilistic relation between diseases and symptoms, more than one symptom pattern can correspond with a disease, so we have a rule for each such symptom pattern.

The Input-Output process

The next thing to do is to open the Input-Output process box and add the rules shown in the figure below.

The first two rules forward any queries or diagnoses in Working Memory to the Experimenter, and are refracted so they only fire once for each query or diagnosis. The third rule is triggered by a message from the Experimenter, and it adds symptom information to Working Memory.

So far, we can't actually run the model, since we have not arranged for appropriate inputs (presenting symptoms) and responses to queries. To do this, we must flesh out the boxes in the experimenter portion of the model, and this is the subject of the next section.

The Experimental Environment

Having completed the Subject subsystem, it is necessary to flesh out the Experimenter subsystem to make the model runnable. This subsystem comprises the following boxes:

The Experimenter process
sets up and administers trials, and responds to input from the Subject.
The Simulation Data buffer
contains the full probability matrix governing the relations between all diseases and symptoms
The Trial Setup buffer
contains temporary and setup information used by the Experimenter during a trial.
The Experiment Record text sink
collects output from the Experimenter.

The Experimenter process

First of all, you should open the Experimenter process box to allow input of its rules and conditions.

The first rule to construct is the one which initialises the trial and sends the presenting symptom to the Subject. This depends on a condition definition, which you should define first, to ensure that it is accessible from the rule editor menus:

   
Condition Definition: pr/3: To generate a presenting symptom
pr(Disease, Symptom, Prob):-
    Rand is randomly drawn from U(0,1)
    Rand =< Prob
    !.

Rule (refracted): Trial set up
IF:   setup(Disease, Symptom, wm(WM), m(Mode)) is in Trial Setup
      not setup_for(Disease, Symptom) is in Trial Setup
      once assoc(Disease, Symptom, Prob) is in Simulation Data
           pr(Disease, Symptom, Prob)
THEN: send told(Symptom, present) to Input-Output
      add setup_for(Disease, Symptom) to Trial Setup
      send trial(presenting(Symptom), with_disease(Disease), wm(WM), m(Mode)) to Experiment Record
      add told(0, Symptom, present) to Trial Setup

The next set of rules are all triggered by receipt of a message from the subject: the first one just records all the subject's output in the Experiment Record:

Rule (unrefracted): Forward all of the subject's output to Trace
TRIGGER: Anything
IF:   true
THEN: send Anything to Experiment Record

Next, we construct a rule to determine whether a symptom is present or absent in response to a query, and respond to the query. Again, this rule depends on a condition definition, so for convenience this should be defined first.

Condition Definition: pa/4: To compute whether symptom is present/absent in response to question
pa(Disease, Symptom, Prob, present):-
    Rand is randomly drawn from U(0,1)
    Rand =< Prob
    !.
pa(Disease, Symptom, Prob, absent).

Rule (refracted): Answer queries from Input-Output by reference to Simulation Data
TRIGGER: ask(Symptom, present)
IF:   setup_for(Disease, _) is in Trial Setup
      once assoc(Disease, Symptom, Prob) is in Simulation Data
           pa(Disease, Symptom, Prob, Value)
      count_questions(N) is in Trial Setup
      Current is (N) + (1)
THEN: send told(Symptom, Value) to Input-Output
      send told(Symptom, Value) to Experiment Record
      add told(Current, Symptom, Value) to Trial Setup
      delete count_questions(N) from Trial Setup
      add count_questions(Current) to Trial Setup

The Trial Setup buffer

In order for the model to work, the experimenter's buffers need initial contents. The Trial Setup buffer should contain a variety of information, defined in its Initial contents view:

Element: Setup for a specified symptom or specified disease or both
setup(hepatitis, vomiting, wm(lifo), m(discrim))

Element: Question count initialisation
count_questions(0)

The Simulation Data buffer

Finally, the Simulation Data buffer's Initial contents should contain knowledge of the diagnostic task, expressed as simple prolog terms of the general form: assoc(Disease, Symptom, Strength). where Disease is one of {tonsillitis, parotitis, laryngitis, meningitis, hepatitis}, Symptom is one of {earache, headache, pyrexia, dysphagia, vomiting} and Strength is a value in [0,1] representing the probability of the association.

Element: Strong association between laryngitis and dysphagia
assoc(laryngitis, dysphagia, 1.00)

Element: Strong association between tonsillitis and dysphagia
assoc(tonsillitis, dysphagia, 1.00)

Element: Strong association between hepatitis and vomiting
assoc(hepatitis, vomiting, 1.00)

Element: Strong association between tonsillitis and headache
assoc(tonsillitis, headache, 1.00)

Element: Strong association between parotitis and earache
assoc(parotitis, earache, 1.00)

Element: Strong association between tonsillitis and earache
assoc(tonsillitis, earache, 1.00)

Element: Strong association between tonsillitis and pyrexia
assoc(tonsillitis, pyrexia, 1.00)

Element: No association between parotitis and dysphagia
assoc(parotitis, dysphagia, 0.00)

Element: No association between hepatitis and dysphagia
assoc(hepatitis, dysphagia, 0.00)

Element: No association between meningitis and dysphagia
assoc(meningitis, dysphagia, 0.00)

Element: No association between parotitis and vomiting
assoc(parotitis, vomiting, 0.00)

Element: No association between laryngitis and vomiting
assoc(laryngitis, vomiting, 0.00)

Element: No association between tonsillitis and vomiting
assoc(tonsillitis, vomiting, 0.00)

Element: No association between hepatitis and headache
assoc(hepatitis, headache, 0.00)

Element: No association between hepatitis and earache
assoc(hepatitis, earache, 0.00)

Element: No association between laryngitis and earache
assoc(laryngitis, earache, 0.00)

Element: High association between meningitis and headache
assoc(meningitis, headache, 0.75)

Element: High association between meningitis and pyrexia
assoc(meningitis, pyrexia, 0.75)

Element: Low association between parotitis and headache
assoc(parotitis, headache, 0.25)

Element: Low qssociation between parotitis and pyrexia
assoc(parotitis, pyrexia, 0.25)

Element: Low association between hepatitis and pyrexia
assoc(hepatitis, pyrexia, 0.25)

Element: Low association between laryngitis and pyrexia
assoc(laryngitis, pyrexia, 0.25)

Element: Moderate association between meningitis and vomiting
assoc(meningitis, vomiting, 0.50)

Element: Moderate association between laryngitis and headache
assoc(laryngitis, headache, 0.50)

Element: Moderate association between meningitis and earache
assoc(meningitis, earache, 0.50)

Running the model

At this point the model is ready to run, so open the Run window from the root compound window and try running a trial. To do this, set the Run window mode to Block mode, set the number of trials per block to 1, and click the Run button. If all is well, you will see messages appear in the lower pane of the Run window, similar to this:

If all is not well, you have probably made a mistake in defining the model.

Assuming the model works correctly, you will notice that rerunning the model always produces the same results. You can control which diseases and presenting symptoms are used by opening the Trial Setup window (Initial contents) and editing the setup element. Changing diseases and presenting symptoms here will result in corresponding changes when you run the model (make sure you pick appropriate presenting symptoms if you do this!).

Also, if you use variables instead of names, you can avoid having to specify diseases or symptoms at all. For example, change the setup element to:

Element: Setup for a specified symptom or specified disease or both
setup(Disease, Symptom, wm(lifo), m(discrim))

Now run a few trials. If diseases and symptoms still don't change, try playing with the access properties of the Simulation Data buffer.


A Model of Addition Overview Model 1a: Elaborating the Experimental Environment