WeBWorK Problems

Does a method exist to say whether or not a Formula uses a given function?

Does a method exist to say whether or not a Formula uses a given function?

by Alex Jordan -
Number of replies: 2

There is this method for a MathObject Formula:

$f->usesOneOf("x",...)

that tells you whether or not a Formula uses some variable. Is there something similar for functions? My objective is to take a student formula (in a custom answer checker) and determine if they are using 'sqrt'. I don't want to disable 'sqrt', I just want to tailor the custom feedback message to whether or not they used it.

I could just print the string for the student formula and see if 'sqrt' appears in that string. It would feel better if there was something that actually looked in the tree for $f.

In reply to Alex Jordan

Re: Does a method exist to say whether or not a Formula uses a given function?

by Davide Cervone -

No such function currently exists. You would either have to walk the parse tree to look for function nodes yourself and could them, or you could subclass the function class to flag whether sqrt was used or not. I'll see if I can put something together to illustrate the latter, when I get a moment.

In reply to Alex Jordan

Re: Does a method exist to say whether or not a Formula uses a given function?

by Davide Cervone -

It turns out this is easier than I thought. Here is a little code that does the trick:

package my::Function;
our @ISA = ('Parser::Function');

sub new {
  my $self = shift;
  my ($equation, $name) = @_;
  $equation->{functions}{$name} = 1;
  $self->SUPER::new(@_);
}

package main;

Context("Numeric")->{parser}{Function} = 'my::Function';

$f = Formula("sin(x+sqrt(x+1))");
TEXT(join(', ', keys %{$f->{functions} || {}}));

This subclasses the Parser::Function object and overrides the new method so that it marks the names of the functions used in the formula. You could use $f->{functions}{sqrt} to determine if sqrt() had been used in the formula.

Note that if you use Compute() rather than Formula(), and the result is a constant, you won't get the functions property because the formula will have been evaluated to the constant, but you can use $f->{equation}{formula} in that case. In an answer checker, you should be able to use $ansHash->{student_value} rather than $ansHash->{student_answer} to access the formula.