## WeBWorK Problems

### Disable/undefine functions/operators on only some parts of an answer

by Abhijit Dasgupta -
Number of replies: 5

Greetings,

I am not an experienced WeBWorK problem writer, and I am looking for suggestions on ways (if any) to implement certain answer restrictions in the following problem that I am trying to write.

Problem 1.  Expand the log expression as far as you can using properties of logarithms:

$\ln \sqrt[3]{\frac{x^2}{1 + \sqrt{x^2 + 1}}}$

The main restrictions in the entered answer that I want are:

(a) "No decimals":  Numerical terms/fractions entered in the answer cannot contain decimal points; and

(b) "Logs fully expanded":  For any occurrence of the ln() function in the answer, its argument, i.e. the expression directly enclosed by the ln() function, cannot be in the form of a product, quotient, or a power operator, or a sqrt function.

(In particular, the answer must be a numerical linear combination of fully expanded log terms where the numerical scalar coefficients do not contain decimal points.)

Examples of acceptable and unacceptable answer entries for the problem:

Acceptable:  (1/3) * (2 * ln(x) - ln(1 + sqrt(x^2 + 1)))

Acceptable:  (2/3) * ln(x) - (ln(1 + sqrt(x^2 + 1)))/3

Unacceptable:  0.333333 * (2 * ln(x) - ln(1 + sqrt(x^2 + 1)))

Unacceptable:  (1/3) * (ln(x^2) - ln(1 + sqrt(x^2 + 1)))

(Also, the answer should not contain irrelevant functions such as sin(), and WeBWorK should display the correct answer with the above restrictions as well.)

I can try to enforce entering of numerical fractions without decimals with Context("Fraction") and "Parser::Number::NoDecimals".  I can also try enforcing log expansion with Context()->functions->disable() and Context()->operators->undefine() on functions/operators like sqrt, "/", "**", "^", etc (as explained in the Introduction to Contexts wiki page), but the problem is that some of those functions/operators need to be allowed in parts of the entered answer.

Any ideas on how can I do the above?

Thanks,

A.D.

Tags:

### Re: Disable/undefine functions/operators on only some parts of an answer

by Alex Jordan -

This would be very hard to do "honestly". WeBWorK is not a computer algebra system, and what you are after is fundamentally about symbolic algebra manipulation.

But you could redefine ln() so that it no longer has the usual properties of logarithms. For example if you redefined it to be 1/sqrt(), then it has the same domain as ln(), and:

(2/3) * ln(x) - (ln(1 + sqrt(x^2 + 1)))/3

is not equivalent to:

(1/3) * (ln(x^2) - ln(1 + sqrt(x^2 + 1)))

nor is it equivalent to:

ln(cbrt(x^2/(1+sqrt(x^2+1))))

Somewhere in these forums is a thread where Davide Cervone explains how to redefine sqrt() to mean something else. That thread is about making things like sqrt(4x) be distinguished from 2sqrt(x), so it is a similar issue. Sorry I can't find the thread right now.

Using the above approach, you may need to insist on things like -ln(x) instead of +ln(1/x).

### Re: Disable/undefine functions/operators on only some parts of an answer

by Abhijit Dasgupta -
Thank you for the idea - this is an interesting workaround!

I could not find the thread that you mentioned via a simple search, but I just tried your method and it seems to work fine!  Here is what I did.

I removed the variable x and added it back with some limits, and then removed the function ln and redefined it using parserFunction.pl.  The key lines are:

<code>
\$CTF->functions->remove("ln");
parserFunction("ln(x)" => "1/sqrt(x)");
</code>

That was it!

Not "honest", but a usable workaround (that can possibly be made safer by using a "worse" replacement function).

### Re: Disable/undefine functions/operators on only some parts of an answer

by Abhijit Dasgupta -
Expanding my last parenthetical comment: It would perhaps be safer to use a "worse" replacement function, since after all f(x) = 1/sqrt(x) has some nice special properties such as being a "multiplicatively odd function", i.e. it satisfies f(1/x) = 1/f(x).

### Re: Disable/undefine functions/operators on only some parts of an answer

by Alex Jordan -

In case it is useful, I found that thread:
https://webwork.maa.org/moodle/mod/forum/discuss.php?d=491

Using that method, you can have the answer checker recognize that (for example) "ln(x(x+1))" is equivalent to "ln(x)+ln(x+1)" but not in the expected form. And you can use that to send a message to students. Like "Your answer is equivalent to the correct answer, but not in the right form. Perhaps you haven't simplified, expanded, factored completely, etc."

Note that things like ln(x^2) are not really equal to 2ln(x) unless you restrict the domain to positive x. So in problems like this, I recommends making sure you set the function test point domain appropriately for each question. Otherwise there can be random seeds where using the default test point domain of [-2,2], some or all test points can end up being negative. And it can cause trouble that you don't encounter until some student gets an unlucky seed.