Let NOTATION.f = OUTER.fText
NOTATION.ddxF = {?}
DERIVATIVE
expr(["*", OUTER.ddxF, randFromArray(INNER.wrongs)])
expr(["*", randFromArray(OUTER.wrongs), INNER.ddxF])
expr(["*", OUTER_WRONG_1, INNER_WRONG_1])
expr(["*", OUTER_WRONG_2, INNER_WRONG_1])
expr(["+", randFromArray(OUTER.wrongs), randFromArray(INNER.wrongs)])
expr(["+", randFromArray(OUTER.wrongs), randFromArray(INNER.wrongs)])
expr(OUTER.ddxF)
expr(randFromArray(OUTER.wrongs))
expr(randFromArray(OUTER.wrongs))
1
NOTATION.ddxF = ( derivative of OUTER.fText with respect to INNER.fText
) \cdot ( derivative of INNER.fText with respect to x)
The derivative of OUTER.fText with respect to INNER.fText is OUTER.ddxFText.
The derivative of INNER.fText with respect to x is INNER.ddxFText.
The derivative at this point is expr(UNSIMPLIFIED_DERIVATIVE), but this expression can be simplified.
expr( i === 0 ? UNSIMPLIFIED_DERIVATIVE : DERIVATIVE_SIMPLIFICATIONS[i - 1] ) can be simplified to expr(newexpr).
So NOTATION.ddxF = DERIVATIVE.
Interestingly, if we simplify the function before we take the derivative, we can reach the answer more quickly: OUTER.fText simplifies to expr(PRE_SIMPLIFICATION), and \frac{d}{dx}(expr(PRE_SIMPLIFICATION)) is DERIVATIVE.