In a Cognitive Tutor, production rules in Jess model student procedural knowledge and misconceptions. A single rule can model either correct knowledge or a misconception, but not both.
A production rule begins with the Jess construct
defrule. For example:
(defrule write-answer ...
In a single rule, a left-hand side (LHS) portion of the rule specifies a pattern to match against the contents of working memory. The right-hand side (RHS) portion of the rule specifies a function or functions to call when the LHS matches. This division is common to all Jess productions rules, not just rules in CTAT. The '=>' symbol separates the LHS (above the '=>') from the RHS (below the '=>').
(defrule add-first-column-no-carry
?problem <- (problem
(interface-elements $? ?table $?)
(subgoals ))
...
=>
(bind ?sum (+ ?num1 ?num2))
(modify ?result (value ?sum))
...
) Rules that model correct knowledge can be named anything you'd like. Ideally, they should reflect the production the student is to learn. Some example production rule names:
add-first-column-no-carry
determine-lcd
determine-reduction-factor
Rules that model a student misconception, however, must be
named with the text bug+ (where "+" is any
non-alphabetic character) or buggy at the
beginning of the rule name. Some example incorrect, or buggy,
production rule names:
BUG-reduce-numerator
buggy-add-next-column-did-not-write-carry
buggy-done
To predict an action that a student should take for a
production rule to be fully activated, use the
predict-observable-action function in the RHS
of your production rule. The syntax of this function is:
(predict-observable-action <selection> <action> <input> <matcherType>?)
<matcherType> is optional. If omitted, an exact match will be used.
This function can also be invoked more concisely as
(predict <selection> <action> <input>
<matcherType>?).
Predict is a special Jess function
provided by CTAT that limits whether or not a production rule can
make changes to working memory. If predict returns false—if the
student does not take the predicted action—then the rule will not
modify working memory, the effects of other function calls on the
RHS of that rule will be undone, and the student's input will be
marked as incorrect. If predict returns true—if the model correctly
predicts the student's action—then the rule will be allowed to make
changes to working memory, and the student's input will be marked as
correct.
Example 2.1. Example use of predict-observable-action
You suspect that for a given production to be true, the student must enter the number '5' in the field called 'firstNum'. You'd call this function in the RHS of the rule as follows:
(predict-observable-action firstNum UpdateTable 5)
In the above example, the <matcherType> argument is omitted.
A matcher is a type of comparison used when determining whether or not the student input matched the predicted input. When the matcherType argument is omitted, an 'exact' match will be used (ie, the predicted input must exactly match that entered by the student).
Other types of matching, defined in Section 3.2.1, “Input Matching”, are specified by using one of the names below:
AnyMatcher
ExactMatcher (default when
matcherType is omitted)
RangeMatcher
RegexMatcher
WildcardMatcher
As each matcher takes different input parameters, the syntax
for each matcher in (predict) is slightly
different:
(predict <selection> <action>
<dummyInput> AnyMatcher)
(predict <selection> <action>
<input> ExactMatcher)
(predict <selection> <action> <input
minimum> <input maximum> RangeMatcher)
(predict <selection> <action>
<regular expression string for input>
RegexMatcher)
(predict <selection> <action> <input
containing wildcards> WildcardMatcher)
An example of calling each matcher is shown below:
(predict ?cell-name "UpdateTable" 999
AnyMatcher)
(predict ?cell-name "UpdateTable" 2
ExactMatcher)
(predict ?cell-name "UpdateTable" 12 14
RangeMatcher)
(predict ?cell-name "UpdateTable" "2[x,y,z]"
RegexMatcher)
(predict ?cell-name "UpdateTable" "The quick brown
fox * the lazy dog." WildcardMatcher)
In addition, you can create your own matcher as a Jess function. For details and an example for defining a new matcher as a Jess function, see Section 4.4.1, “Writing a matcher function”.
(Predict) returns false or throws an exception to halt Rete, the Jess pattern matching algorithm, if the student's action doesn't match the function's three arguments.
To add one or more messages to the list of hint or feedback
messages available to the student, use the
(construct-message) function in the RHS of your
production rule.
(construct-message) works by
concatenating its arguments to form messages: square brackets ([ ])
delimit one message from another.
Example 2.2. Adding hint messages
Below, we add a sequence of four hint messages for the student who is stuck on this rule:
(defrule done
?problem <- (problem (answer-fractions $? ?unreduced-answer $?))
?unreduced-answer <- (fraction (numerator ?num) (denominator ?denom))
?num <- (textField (value ?n&:(neq ?n nil)))
?denom <- (textField (value ?d&:(neq ?d nil)))
(test (eq (gcd ?d ?n) 1))
=>
(predict done ButtonPressed -1)
(construct-message
[ Is there anything else to do?]
[ If the greatest common divisor of a numerator and a denominator is 1,
then the fraction cannot be further reduced.]
"[The greatest common divisor of " ?d " and " ?n " is 1.]"
[ You are done. Press the done button.]
)
)![]() | Note |
|---|---|
To reference variables in the
|
To create a feedback message for an incorrect action by the student, use the same syntax of (construct-message), but in a buggy rule.
![]() | Note |
|---|---|
Parentheses in (construct-message
["Start with the column on the right. (This
is the 'ones' column.)" ])
(construct-message
["Move on to the" ?pos "column from the
right. (This is the" ?col-name "column.)"]) |
For more information on writing production rules in Jess, see Chapter 6 "Making Your Own Rules" of the official Jess language reference.
For documentation of existing Jess functions, see the Jess Function List of the Jess language reference.