In this section, you will be defining the types of arguments you will be using and also adding an operator / constraint / feature-predicate/input matcher to the existing SimStudent. This assumes you have downloaded SimStudent Author's Toolkit and configured it with the CTAT Tutor. If not, you must first go through the SimStudent Author's ToolKit. Prerequisites:
Defining types of arguments and a Type Checker 1. Make a Java class First you have to define the different types of arguments you will use in the target domain, and a method that given an argument returns what the type of that argument (i.e. the "type checker") . For example, for the domain of algebra equations appropriate types might be "algebraic expression", "number", "coefficient", whereas for fraction addition appropriate types might be "complex fraction", "mixed fraction" etc. In this example, you will be defining types and a type checker for a hypothetical domain that involves two different types: "numbers" and "words". To do so, you must first create a class named e.g. "MyFeaturePredicates" in the same package that you copied the files from the SimStudent. This class must extend the "FeaturePredicate.class" and will contain
/********************************************************************* ********************************************************************** ************************MyFeaturePredicate.java*********************** ********************************************************************** **********************************************************************/ package packagename; import java.util.Vector; import edu.cmu.pact.miss.FeaturePredicate; public abstract class MyFeaturePredicate extends FeaturePredicate{ /*definition of the types*/ public static final int TYPE_NUMBER = 11; public static final int TYPE_WORD = 12; /*function that checks if a string represents a word or a number*/ private boolean isNumber(String line){ return line.matches("[+-]?\\d*(\\.\\d+)?"); } /*the type checker. This function is invoked by SimStudent to determine the type of a string value*/ public static Integer valueTypeCheckerForMyDomain( String value ) { int valueType; if (isNumber(value)) { valueType = TYPE_NUMBER; } else { valueType = TYPE_WORD; } return new Integer(valueType); } } 2. Updating the files Now you need to make changes on one file in the same folder where your tutoring interface java file is located. You should have the file "runTutor.sh" in this folder. For SimStudent to invoke the function "valueTypeCheckerForMyDomain" in order to determine the type of an argument, you must add the line TutorArg="${TutorArg} -ssTypeChecker packageName.valueTypeCheckerForMyDomain" in your runTutor.sh file. Adding an operator
1. Make a Java class First, you write our own operator in the same package where you copied the files from the SimStudent Toolkit. Operators are generic functions to manipulate various form of objects involved in a target task. For example, Algebra operators addTerm("3x", "2x") returns "5x" and getCoefficient("-4y") returns "-4". In this example, you will be developing an operator which can concatenate two words. Let us call this file Concatenate.java. For this you can copy the code below and paste it in a file Concatenate.java But before you proceed, make sure you understand the entire structure of the class. Here we define a class Concatenate.java which extends the MyFeaturePredicate class (defined in the section "Defining types of arguments"). This class has a constructor "Concatenate()" in which we can set the following fields.
/********************************************************************* ********************************************************************** ************************Concatenate.java****************************** ********************************************************************** **********************************************************************/ package packagename; // packagename is the package where you put this file. import java.util.Vector; import packagename.MyFeaturePredicate; public class Concatenate extends MyFeaturePredicate { private static final long serialVersionUID = 1L; public Concatenate() { setArity(2); setName("concatenate"); setReturnValueType(TYPE_WORD); setArgValueType(new int[]{TYPE_WORD, TYPE_WORD}); } public String apply(Vector args) { String expString1 = (String)args.get(0); String expString2 = (String)args.get(1); return (expString1 + expString2); } } 2. Updating the files Now you need to make changes to two files in the same folder where your Concatenate.java is located. You should have the following two files in your folder - operators.txt and UserDefSymbols.java.
rete.addUserfunction(new Concatenate()); 3. compileMyTutor.sh -Now run compileMyTutor.sh (on Mac or Linux) and compileMyTutor.bat (on Windows). Adding a feature-predicate 1. Make a Java class The method of defining a feature-predicate is similar to adding an operator for the SimStudent. A feature-predicate is a boolean function that tests the existence of a certain feature. For example, isPolynomial("3x+1") returns true, but isConstantTerm("3x") returns false. Instead of returning true/false, a feature predicate function returns the string "T" when the feature exists, "null" otherwise. The newly created class must extend the class "MyFeaturePredicate" you previously defined in the section "Defining types of arguments". Just like with the operators, the arguments passed to the "apply()" function of this class is the value of a working memory element (e.g. the value of a cell, or a text box). In this example, you will be writing a feature-predicate to check if a number is negative. /********************************************************************* ********************************************************************** ************************IsNegative .java.java******************************** ********************************************************************** **********************************************************************/ package packagename; // packagename is the package where you put this file. import java.util.Vector; import jess.Fact; import jess.JessException; import jess.Rete; public class IsNegative extends MyFeaturePredicates. { public IsNegative() { setArity(1); setName("is-negative"); setArgValueType(new int[]{TYPE_NUMBER}); } public String apply(Vector args) { String expString=(String)args.get(0); return (expString.charAt(0)=='-') ? "T" : null; } } 2. Updating the files Now you need to make changes to two files in the same folder where your IsNegative.java is located. You should have the following two files in your folder - feature-predicates.txt and UserDefSymbols.java.
rete.addUserfunction(new IsNegative()); 3. compileMyTutor.sh -Now run compileMyTutor.sh (on Mac or Linux) and compileMyTutor.bat (on Windows). Adding a constraint
1. Make a Java class
The constraint defines physical relations among working memory elements (i.e., components on the tutoring interface such as text boxes and cells). The method of defining constraints is similar to defining operators for the SimStudent except that the new class extends TableConstraint. In this example, you will be writing a constraint that checks if the two cells are in the consecutive row. As you will notice in the example bellow, one difference between an operator / feature-predicate and a constraint is that in a constraint, the arguments passed in the "apply()" function are Jess facts and not their values (i.e. the Jess fact that represents a cell and not the value in the cell). /*********************************************************************
********************************************************************** ************************ConsecutiveRow.java*************************** ********************************************************************** **********************************************************************/ package packagename; // packagename is the package where you put this file. import java.util.Vector;
import jess.Fact;
import jess.JessException; import jess.Rete; public class ConsecutiveRow extends TableConstraint {
public ConsecutiveRow() {
setArity(2); setName("consecutive-row"); } public String apply(Vector args,Rete rete) {
try { return consecutiveRow((Fact)args.get(0),(Fact)args.get(1),rete); } catch(JessException e) { e.printStackTrace(); return null; } } } 2. Updating the files Now you need to make changes to two files in the same folder where your ConsecutiveRow.java is located. You should have the following two files in your folder - constraints.txt and UserDefSymbols.java.
rete.addUserfunction(new ConsecutiveRow()); 3. compileMyTutor.sh -Now run compileMyTutor.sh (on Mac or Linux) and compileMyTutor.bat (on Windows). Defining an Input Matcher 1. Make a Java class Finally, you must specify you own domain dependent input matcher, in the same package you copied the files from SimStudent toolkit. An "input matcher" is a feature predicate that takes two string arquments (expressions) as an input, and determines if these two expressions are equivalent. The "equivalence" of two expressions is defined by the target domain. For example, strings "6" and "4+2" may not be the same, but in the algebra domain they express the same thing. Thus the input matcher for the algebra domain should return true (i.e. "T") when given these arguments. In the following example, an input matcher is presented that checks if two strings are identical. /********************************************************************* ********************************************************************** ************************IsEquivalent.java****************************** ********************************************************************** **********************************************************************/ package packageName; import java.util.Vector; import edu.cmu.pact.miss.FeaturePredicate; public class IsEquivalent extends FeaturePredicate{ public IsEquivalent() { setArity(2); setName("is-equivalent"); } public String apply(Vector args) { inputMatcher((String)args.get(0),(String)args.get(1)) } public String inputMatcher(String exp1, String exp2){ return (exp1.equals(exp2)? "T" : null; } } 2. Updating the files Now you need to make changes on one file in the same folder where your Square.java is located. You should have the file "runTutor.sh" in this folder. For SimStudent to use the input matcher you have defined, you must add the line TutorArg="${TutorArg} -ssInputMatcher packageName.IsEquivalent" in your runTutor.sh file. Notes It is recommended that before running the tutor you remove from the following files any operator, feature predicate, or constraint that you have not written for your domain:
Last Updated May 21, 2015 |
User's Guide > Advanced Users >