# Formula Functions

CTAT defines functions can be used in formulas to match student input and customize hint and error messages in example-tracing tutors. These formulas can be used in the Edit Student Input Matching dialog as shown in the example below:

For more information on how to use functions, see Generalizing an example-tracing tutor with formulas. Below are the functions provided by CTAT:

Jump to A, C, D, E, F, G, H, I, L, M, N, O, P, Q, R, S, Math and String functions

## algEquiv

algEquiv(expression1, expression2)

• Arguments:
• expression1 - `<String>` An algebraic expression
• expression2 - `<String>` An algebraic expression
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Determine whether 2 algebraic expressions are equivalent when fully simplified.

Also callable from Jess code: `(algEquiv "expression1" "expression2")`.

Example Usage

`algEquiv(input, "4x+9")`

returns true if the student input is "9 + 4x" or "9+2x+2x"

More examples of behavior, where == and != indicate that the function returns true or false, respectively:

expression1 expression2
2x + x - 3 + 5 == 2*x + x + (-3) + 5
2x + x - 3 + 5 == x*2 + 1x + 5 - 3
2x + x - 3 + 5 == 3x + 2
2(x + x - 3) + 5*2 == 2(x + 1x - 3) + 2*5
2(x + x - 3) + 5*2 == (x + 1x - 3)2 + 2*5
2(x + x - 3) + 5*2 == (x + x*1 - 3*1)2 + 2*5
2(x + x - 3) + 5*2 == 5*2 + (x + x + (-3))2

## algEquivTerms

algEquivTerms(expression1, expression2)

• Arguments:
• expression1 - `<String>` An algebraic expression
• expression2 - `<String>` An algebraic expression
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Determine whether 2 algebraic expressions are equivalent when simplified to discrete terms. This function will declare 2 expressions equivalent if their differences are limited to order of commutative operands, redundant parentheses and notational variants (2*x and 2x).

Also callable from Jess code: `(algEquivTerms "expression1" "expression2")` returns TRUE or FALSE.

Example Usage

`algEquivTerms(input, "4x+9")`

returns true if the student input is "9 + 4x" but false if it's "9+2x+2x".

More examples of behavior, where == and != indicate that the function returns true or false, respectively:

expression1 expression2
2x + x - 3 + 5 == 2*x + x + (-3) + 5
2x + x - 3 + 5 == x*2 + 1x + 5 - 3
2x + x - 3 + 5 != 3x + 2
2(x + x - 3) + 5*2 == 2(x + 1x - 3) + 2*5
2(x + x - 3) + 5*2 == (x + 1x - 3)2 + 2*5
2(x + x - 3) + 5*2 == (x + x*1 - 3*1)2 + 2*5
2(x + x - 3) + 5*2 == 5*2 + (x + x + (-3))2

## algEquivTermsSameOrder

algEquivTermsSameOrder(expression1, expression2)

• Arguments:
• expression1 - `<String>` An algebraic expression
• expression2 - `<String>` An algebraic expression
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Determine whether 2 algebraic expressions are equivalent when simplified to discrete terms. This function will declare 2 expressions equivalent if their differences are limited to order of commutative factor, redundant parentheses and notational variants (2*x and 2x). Unlike algEquivTerms, it will require that addends be in the same order.

Also callable from Jess code: `(algEquivTermsSameOrder "expression1" "expression2")` returns TRUE or FALSE.

Example Usage

`algEquivTermsSameOrder(input, "4x+9")`

returns true if the student input is "x*4 + 9" but false if it's "9+4x" or "2x+2x+9"

More examples of behavior, where == and != indicate that the function returns true or false, respectively:

expression1 expression2
2x + x - 3 + 5 == 2*x + x + (-3) + 5
2x + x - 3 + 5 != x*2 + 1x + 5 - 3
2x + x - 3 + 5 != 3x + 2
2(x + x - 3) + 5*2 == 2(x + 1x - 3) + 2*5
2(x + x - 3) + 5*2 == (x + 1x - 3)2 + 2*5
2(x + x - 3) + 5*2 == (x + x*1 - 3*1)2 + 2*5
2(x + x - 3) + 5*2 != 5*2 + (x + x + (-3))2

## algEval

algEval(expression1)

• Arguments:
• expression1 - `<String>` An algebraic expression
• Returns: `<Number>` - Result of evaluating the expression
• Description: Attempt to evaluate an expression given the variable table and BRD-specific settings.

Also callable from Jess code: `(algEval "expression1")` returns a number.

Example Usage

`algEval("4x+9")`

returns 41 if x=8 in the variable table.

## and

and(condition1, condition2, ..., conditionN)

• Arguments:
• condition1 ... conditionN - `<Boolean>` Expressions that return TRUE or FALSE; all arguments are optional
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if two or more conditions are true. Returns FALSE if any condition is not true. As a special case, if no argument is given, returns TRUE.

Example Usage

`and(greaterThan(input,0),lessThan(input,100))`

returns true if the student input is between 0 and 100.

## assign

assign(name, value)

• Arguments:
• name - `<String>` A variable name
• value - A value to assign to the variable (Optional)
• Returns: The value of the variable if one is assigned; otherwise the result is undefined
• Description: Mechanism for saving values in the current variable table, specific to the interpretation in whose context this function is called.

Example Usage

`assign("myvar", "blue")`

creates a variable (if none exists) with the name "myvar" and assigns the string value "blue".

`assign("mynum", 50)`

creates a variable (if none exists) with the name "mynum" and assigns the numeric value 50.

`assign("myvar")`

removes a variable (if any exists) by the given name "myvar".

## chooseRandomly

chooseRandomly(arg1, arg2, ..., argN)

• Arguments:
• arg1 ... argN - Values from which to choose. At least one argument is required; additional arguments are optional.
• Returns: The randomly chosen value.
• Description: Choose one of two or more argument values at random. Values can be strings, numbers, variables, etc.
`chooseRandomly("x","y","z")`

returns "x", "y", or "z".

## concat

concat(arg1, arg2, ..., argN)

• Arguments:
• arg1 ... argN - `<String>` Strings to concatenate. At least one argument is required; additional arguments are optional.
• Returns: `<String>` - The result of concatenating all of the arguments as strings.
• Description: Concatenate two or more strings into one string.

Example Usage

`concat("You entered ",input," pizzas.")`

returns "You entered 3 pizzas" if the student input is 3.

## constantsConform

constantsConform(expr, pattern1, ..., patternN)

• Arguments:
• expr - `<String>` An arithmetic expression with numbers
• pattern1 ... patternN - `<String>` Regular expressions; each number should match one or more patterns. At least one pattern is required; additional patterns are optional.
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if the constants in an expression conform to one or more patterns. This can be used, e.g., to verify that all the numeric values in an equation are either integers or dollar amounts (d.dd).

Example Usage

`constantsConform("15 + 8 = x","\d+")`
`constantsConform("24-x = 7.50","[0-9]+","[0-9][.][0-9][0-9]")`

returns true if the numeric constants in the expression conform to at least one of the patterns.

## constantsDollar

constantsDollar(expr)

• Arguments:
• expr - `<String>` An arithmetic expression
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check that each number in an expression is either an integer or a dollars-and-cents (d.dd) value.

Example Usage

`constantsDollar("25.00")`

returns true.

`constantsDollar("1.50 + 8")`

returns true.

`constantsDollar("1.5 + 8")`

returns false.

## deliverDelayedFeedback

Send any delayed feedback messages.

## equals

equals(arg1, arg2, ..., argN)

• Arguments:
• arg1 ... argN - `<String>` or `<Number>` Values to compare. At least one argument is required; additional arguments are optional.
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if two or more values are equal.

Example Usage

`equals(0, x, input)`

returns false if the variable "x" is set to 0 but the student input is 1.

`equals("addition", input)`

returns true if the student input is "addition".

## eval

Simplify an expression.

In most cases, it is unnecessary to use the eval function explicitly in formulas. Instead, you can use the expression itself as the formula, e.g., "input/2".

Example Usage

`eval(input/2)`

returns 5 if the student input is 10.

## firstNonNull

firstNonNull(arg1, ..., argN)

• Arguments:
• arg1 ... argN - Values to search. At least one argument is required; additional arguments are optional.
• Returns: The left-most non-null argument value. If all values are null, null is returned.
• Description: Search one or more argument values for the first non-null value.

Example Usage

`firstNonNull(x, y, 0)`

returns 5 if the variable "y" is set to 5 and the variable "x" has no value set.

## fmtDecimal

fmtDecimal(number, precision)

• Arguments:
• number - `<Number>` A number to format
• precision - `<Integer>` Number of decimal places (Optional)
• Returns: `<String>` - Formatted number
• Description: Format a decimal number to have the given precision. If precision is zero, omits the decimal point (i.e., rounds to integer). If no precision is specified, precision defaults to 2.

Example Usage

`fmtDecimal(input)`

returns 5.56 if the student input is 5.559.

`equals(fmtDecimal(input, 3),"3.101") `

returns true if the student input, when formatted to 3 decimal points, is equal to 3.101.

## fmtDollar

fmtDollar(number, flags)

• Arguments:
• number - `<Number>` A number to format
• flags - `<String>` "I", "D", or "ID" (Optional)
• Returns: `<String>` - Formatted number
• Description: Format a decimal number to have 2 digits to the right of the decimal. If the flags argument contains an "I", then return integer dollar amounts without the trailing ".00". If flags contains a "D", then prefix a dollar sign. If the flags argument contains an "ID", then return integer dollar amounts without the trailing ".00" and prefix a dollar sign.

Example Usage

`concat("You entered",fmtDollar(input),".") `

returns "You entered 11.02." if the student input is "11.015".

`concat("You entered",fmtDollar(input,"D"),".") `

returns "You entered \$3.00." if the student input is "3".

## fmtNormal

fmtNormal(number, precision)

• Arguments:
• number - `<Number>` A number to format
• precision - `<Integer>` Number of significant digits (Optional)
• Returns: `<String>` - Formatted number
• Description: Format a number as a calculator would: as an integer if no fractional part; else with up to 6 digits right of the decimal point, but no trailing zeros.

Example Usage

`fmtNormal(input) `

returns 1.333333 if the student input is 1.33333334.

`fmtNormal(input, 2)`

returns 9.46 if the student input is 09.4559

## gcf

gcf(number1, number2)

• Arguments:
• number1 - `<Number>` A number
• number2 - `<Number>` A number
• Returns: `<Number>` - Returns the largest number that divides evenly into both numbers.
• Description: Get the greatest common factor of 2 numbers.
`gcf(input,8)`

returns 4 if the student input is 12.

## getDenominator

getDenominator(fraction)

• Arguments:
• fraction - `<String>` A fraction string formatted as "nnn/ddd"
• Returns: `<String>` - Returns the denominator in a fraction string.
• Description: Get the denominator from a fraction string.
`getDenominator("13/687")`

returns "687".

`getDenominator("3 4/5")`

returns "5".

## getNumerator

getNumerator(fraction)

• Arguments:
• fraction - `<String>` A fraction string formatted as "nnn/ddd"
• Returns: `<String>` - Returns the numerator in a fraction string.
• Description: Get the numerator from a fraction string.
`getNumerator("13/687")`

returns "13".

`getNumerator("3 4/5")`

returns "4".

## goToStartState

Return the graph to the start state.

## greaterThan

greaterThan(value1, value2)

• Arguments:
• value1 - `<String>` or `<Number>` A value to compare
• value2 - `<String>` or `<Number>` A value to compare
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if value1 is greater than value2. Returns true if the first value is greater than the second, false otherwise. If the values cannot both be converted to numbers, then compares lexicographically, ignoring case.
`greaterThan(input, 9)`

returns true if the student input is "10".

## hasValue

hasValue(arg1, ..., argN)

• Arguments:
• arg1 ... argN - Variables to check. At least one argument is required; additional arguments are optional.
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if all arguments have a value set (are non-null).

Example Usage

`hasValue(link1.input,link3.input) `

returns true if the student has entered input for both link1 and link3.

## ifThen

ifThen(condition, thenValue, elseValue)

• Arguments:
• condition - `<Boolean>` A statement that returns TRUE or FALSE
• thenValue - Value to return if condition evaluates to true
• elseValue - Value to return if condition evaluates to false
• Returns: Returns thenValue if test is true, elseValue otherwise.
• Description: Simulate an if-then-else statement.

Example Usage

`ifThen(greaterThan(input,9), input - 10, 0) `

returns 2 if the student input is 12 (i.e., greater than 9), and returns 0 if the student input is 5 (i.e., not greater than 9).

## integerInRange

integerInRange(number, floor, ceiling)

• Arguments:
• number - `<Number>` Number to test; will convert to integer
• floor - `<Number>` Low end of the range; will convert to integer
• ceiling - `<Number>` High end of the range; will convert to integer
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check whether an integer is within the range specified by the arguments, inclusive. Returns false if number is null. Returns true if number is greater than or equal to floor and number is less than or equal to ceiling.

Example Usage

`integerInRange(input, 0, 9.99) `

returns true if the student input is 0, 9.99, or any number in between.

## isAlgValid

isAlgValid(expression)

• Arguments:
• expression - `<String>` An algebraic expression
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Determine whether the argument is a valid algebraic expression.

Example Usage

`isAlgValid(input) `

returns true if the student input is "3y+2x+4"; returns false if the student input is "3y*+2x+4".

## isInteger

isInteger(value, toStringOk)

• Arguments:
• value - `<Number>` Number to test
• toStringOk - `<Boolean>` Allow the value to be a string (e.g., "25"); if false, value must be numeric (Optional)
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Test if the argument is an integer. If toStringOk is not specified, toStringOk defaults to true. Returns true if the argument can be interpreted as an integer, false otherwise.

Example Usage

`isInteger(input) `

returns true if the student input is 3.0; returns false if the student input is 3.5.

`isInteger(x,false) `

returns true if x is 10; returns false if x is "10".

## isNumber

isNumber(value, toStringOk)

• Arguments:
• value - `<Number>` Number to test
• toStringOk - `<Boolean>` Allow the value to be a string (e.g., "4.20"); if false, value must be numeric (Optional)
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Test if the argument is an number. If toStringOk is not specified, toStringOk defaults to true. Returns true if the argument can be interpreted as an number, false otherwise.

Example Usage

`isNumber(x) `

returns true if x is an integer or decimal value; returns false otherwise.

`isNumber(input,true) `

returns true if the student input is, for example, "6" or 6.5; returns false if the student input is 12x.

## last

last(arg1, ..., argN)

• Arguments:
• arg1 ... argN - Arguments to evaluate. At least one argument is required; additional arguments are optional.
• Returns: The evaluation of argument argN
• Description: Evaluates arguments sequentially and returns the evaluation of the last argument. This function can be used when you want to execute some other functions for their side effects but return an arbitrary value.

Example Usage

`last(assign("firstName", "fred"), input)`

assign the String value "fred" to variable firstName and return the student's input.

## lcm

lcm(number1, number2)

• Arguments:
• number1 - `<Number>` A number
• number2 - `<Number>` A number
• Returns: `<Number>` - Returns the smallest number that is a multiple of both numbers.
• Description: Get the least common multiple of 2 numbers.

Example Usage

`lcm(6, input)`

returns 12 if the student input is 4.

## lessThan

lessThan(value1, value2)

• Arguments:
• value1 - `<String>` or `<Number>` A value to compare
• value2 - `<String>` or `<Number>` A value to compare
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if value1 is less than value2. Returns true if the first value is less than the second, false otherwise. If the values cannot both be converted to numbers, then compares lexicographically, ignoring case.
`lessThan(input, 10)`

returns false if the student input is "10".

## matchWithoutPrecision

matchWithoutPrecision(value, number)

• Arguments:
• value - `<Number>` Numeric value to test; if more precise than number, this value will be rounded before it is compared to number.
• number - `<Number>` Number to match against
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if value matches number exactly or matches after rounding if value is more precise than number.

Example Usage

`matchWithoutPrecision(input, 10) `

returns true if the student input is 9.99.

## matchWithPrecision

matchWithPrecision(value, number)

• Arguments:
• value - `<Number>` Numeric value to test; if more precise than number, this value will be rounded before it is compared to number.
• number - `<Number>` Number to match against
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if value matches number numerically and also has the same precision.
`matchWithPrecision(input, .5) `

returns true if student input is 0.5, and returns false if student input is 0.51.

## memberOf

memberOf(value, arg1, ..., argN)

• Arguments:
• value - Value to check.
• arg1 ... argN - Values to compare against the first argument. At least one argument is required; additional arguments are optional.
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Check if the first argument value is equal to any of the other arguments.

Example Usage

`memberOf(input, x, y, z) `

returns true if the student input is "x", "y", or "z".

## mod

mod(n, m)

• Arguments:
• n - `<Number>` Dividend; if not an integer, will convert to integer by rounding.
• m - `<Number>` Divisor (i.e., modulus); if not an integer, will convert to integer by rounding.
• Returns: `<Number>` - The remainder of n divided by m
• Description: Remainder function.

Example Usage

`mod(input, 4) `

returns 2 as the remainder if the student input is 9.99.

## modf

modf(n, m)

• Arguments:
• n - `<Number>` Dividend; if not an integer, will convert to integer by rounding.
• m - `<Number>` Divisor (i.e., modulus); if not an integer, will convert to integer by rounding.
• Returns: `<Number>` - The floating-point remainder of n divided by m
• Description: Remainder function.

Example Usage

`modf(input, 5) `

returns 0.3 if the student input is 10.3.

## not

not(condition)

• Arguments:
• condition - `<Boolean>` A statement that returns TRUE or FALSE
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Function to simulate a negation operator. Returns true if condition is false, false if condition is true.

Example Usage

`not(equals(input, 10)) `

returns true if the student input is not 10 (i.e., the equals function returns false).

## or

or(condition1, ..., conditionN)

• Arguments:
• condition1 ... conditionN - `<Boolean>` Statements that return TRUE or FALSE. At least one condition is required; additional conditions are optional.
• Returns: `<Boolean>` - TRUE or FALSE
• Description: Returns true if any condition is true, false otherwise.

Example Usage

`or(equals(input, 10),equals(input, 5)) `

returns true if the student input is 10 or 5.

## plural

plural(count, word)

• Arguments:
• count - `<Integer>` A value specifying whether or not to pluralize word. If count < 2, return word, otherwise return the plural form of word.
• word - `<String>` A string
• suffixToStrip - `<String>` Characters to remove from the end of the word (Optional)
• suffixToAdd - `<String>` Characters to add to the end of the word (Optional)
• Returns: `<String>` - Singular or plural form of a word
• Description: Under control of a given count, return the singular or plural form of a word. If the given count is greater than one, make the given word plural by adding an "s". If the given count is greater than one and a suffix to remove and add are specified, make the given word plural by removing a given suffix and appending a different one.

Example Usage

`plural(2, "apple") `

returns "apples" as the plural form of "apple".

`plural(2, "datum", "um", "a") `

returns "data" as the plural form of "datum".

## printf

Format a string with optional arguments inserted, using C-style "%" format specifiers.

Example Usage

`printf("You have %d %s.", value1+value2, "books") `

returns "You have 6 books." when value1 is 2 and value2 is 4.

## quote

quote(text)

• Arguments:
• text - `<String>` A string to quote
• Returns: `<String>` - Returns string, quoted.
• Description: Quote a given string. Embedded double-quotes are escaped by backslashes.

Example Usage

`concat("How many ",quote(input), " dogs?") `

returns "How many "big" dogs?" when the student input is "big".

## regExMatch

regExMatch(pattern, teststr, flags)

• Arguments:
• pattern - `<String>` A regular expression
• teststr - `<String>` A string to test
• flags - `<String>` Case-insensitive letters for flags for regular expression patterns (Optional)
• Returns: `<Boolean>` - TRUE or FALSE.
• Description: Test whether a regular expression accepts a test string.

Flags

• 'i': CASE_INSENSITIVE;
• 'm': MULTILINE;
• 'u': UNICODE_CASE;

Example Usage

`regExMatch("x|y", input, "i") `

returns true if the student input is "x", "X", "y", or "Y".

## round

round(n)

• Arguments:
• n - `<Number>` A number.
• Returns: `<Integer>` - An integer.
• Description: Round a number to the closest integer.

Example Usage

`round(input) `

returns 3 if the student input is 2.59.

## runProcess

Experimental class for running an external process.

## sum

sum(arg1, ..., argN)

• Arguments:
• arg1 ... argN - `<Number>` Numbers to add. At least one argument is required; additional arguments are optional.
• Returns: `<Number>` - the sum of all arguments
• Description: Add two or more values and return the result.

Example Usage

`sum(input, value1) `

returns 10 if the student input is "4" and value1 is 6.

## Math and String functions

CTAT supports basic Math and String functions commonly defined in Java and JavaScript. Properties and constants, such as `Math.PI`, are not generally supported, though some may work in JavaScript. For convenience, links to the Java documentation are provided below:

Example Usage

`equals(input, Math.sqrt(value1)) `

returns true if the student input is "5" and value1 is 25.

`String.toLowerCase(input) `

returns "e" if the student input is "E".