How do you determine whether two expressions are equivalent? This seems like a simple question, but it is actually quite complicated and depends on the situation. For that reason, Derivita provides several different tests for equivalence. This page explains each, and when you might choose to use them.
The difference between assert_* and is_*: Calling any function whose name starts with "assert" will increment the max score, and if the function returns true, increment the earned score. Their counterparts that start with "is" just return true or false without affecting the score.
This is the strictest test: it returns true if both expressions are exactly the same. For example, is_equal(1+x, 1 + x) is true, but is_equal(1 + x, x + 1) is false. Because it is so strict, it can be brittle, and should usually be avoided.
This test is similar to is_equal, but it allows terms to be rearranged according to the commutative properties of addition and multiplication. For example, is_commutative_equal(1 + x*y/2, 1/2*y*x + 1) is true. It does not allow any other simplifications though, so is_commutative_equal(x + x, 2x) is false.
This test returns true if the CAS considers the two expressions to be algebraically equivalent. For expressions A and B, is_equivalent(A, B) returns true if simplify(A - B) = 0. For example, this test treats x + x and 2x as equivalent.
If A and B are lists or matrices, it returns true if every item in (A - B) is zero.
If A and B are equations, it returns true if one equation can be turned into the other by adding, subtracting, multiplying, and dividing by constants. For example, this test treats y = 2x as equivalent to 2y + 1 = 4x + 1.
Caveats: The CAS sometimes has trouble with expressions that contain trigonometric functions or complicated expressions in the denominator of a fraction. In these cases, is_near is probably a better choice.
This test uses numerical approximation to determine if two expressions are approximately equal. In the simplest case, it compares two numbers (or numerical expressions): is_near(A, B, tolerance := 0.1) returns true if |A - B| <= 0.1.
When A and B are expressions that contain variables, it will run 20 tests with different values for each variable, and return true if each test has a difference within the tolerance. The default tolerance is 0 and the default range is [-10, 10]. You can override the range for the variable V by passing an argument V_range := range. For example, is_near(A, B, x_range := [-20, 20], y_range := list(0, 16]). Because the selection of values to check is arbitrary, it may miss values that are critical for your expression. For example, is_near(test(x < 3, 5, 1), test(x <= 3, 5, 1)) may return true. You can ensure that specific values are tested for variable V by passing an argument V_range := values. For example, is_near(test(x < 3, 5, 1), test(x <= 3, 5, 1), x_values := [3]).
For equations, this test works similarly to assert_equivalent, but with a scaled tolerance. For example, is_near(y = x + 1, 4y = 4x + 4.4, tolerance := 0.11) is true.
Caveats: This test does not support imaginary numbers, so you need to set your range appropriately. For example, set y_range := [0, 10] for the expression sqrt(y). If you want to set a range exclusive of the endpoints, you can use the syntax x_range := list(a, b), which follows interval inclusion/exclusion notation.
This test uses numerical approximation to compare intervals.
assert_interval_near(union(list(-infinity, -2], list[3, infinity)), union(list[3.09, infinity), list(-infinity, -2.09]), tolerance := 0.1) returns True.